找回密码
 注册SCIFIFANS!
首页 科技专区 全栈 Scrapy+GitHubActions部署云爬虫

Scrapy+GitHubActions部署云爬虫

7
回复
7731
查看
[ 复制链接 ]

该用户从未签到

10

主题

51

回帖

404

积分

Judgement

积分
404
<

用邮箱/用户名来登录sci-fifans!

您需要 登录 才可以下载或查看,没有账号?注册SCIFIFANS!

x
本帖最后由 skyone 于 2021-3-22 13:00 编辑
原文:我的博客
标题:scrapy+GitHubActions部署云爬虫
禁止转载,部分引用请著名出处
为了学习GitHub Actions的基本使用,写一个爬虫练练手
这个爬虫用于下载哔哩哔哩相簿的图片
该文章分为三步:
  • 写爬虫
  • 写workflows文件
  • 上传代码到GitHub

懒得打代码就直接Fork我的仓库:
  1. # https
  2. https://github.com/skyone-wzw/action.git
  3. # ssh
  4. git@github.com:skyone-wzw/action.git
复制代码
重点是GitHub Actions云爬虫不需要自己的服务器,还可以访问wai wang!咳咳咳,总之,懂的都懂。
GitHub Actions 为开源软件提供免费服务器,配置如下
E5 2vCPU/7G RAM
对于公开仓库可免费无时间限制的使用,且单次使用时间长达 6 个小时
对爬虫来说,有以下优点
  • 免费
  • 万兆自由网络环境
  • 定时爬取
  • 并发(可同时进行20个任务)
  • 无需担心磁盘空间不足(近60G磁盘空间)

写一个scrapy爬虫创建项目
新建一个项目文件夹,打开CMD并切换到该文件夹,输入以下命令初始化git:
git init
使用scrapy新建项目并新建爬虫:
scrapy startproject bili bilibili.com
cd bili
scrapy genspider picture
创建项目完毕,下面使用IDE打开项目文件夹吧~
我使用的是Pycharm
储存图片信息的class
打开bili/items.py,不出意外的话,这里已经有一个BiliItem(scrapy.Item)类了
我们将其改为:
  1. import scrapy


  2. class BiliItem(scrapy.Item):
  3.     url = scrapy.Field()        # 图片连接
  4.     title = scrapy.Field()      # 图片标题
  5.     author = scrapy.Field()     # 作者
  6.     id = scrapy.Field()         # 图片id
  7.     uid = scrapy.Field()        # 作者uid
  8.     extension = scrapy.Field()  # 图片拓展名
复制代码
分析哔哩哔哩API
打开哔哩哔哩相簿,开启检查元素的网络那一栏,发现每加载一次都会有一个get请求:
很好,正是我们想要的,多次尝试,很容易分析出来:
  1. GET https://api.vc.bilibili.com/link ... _num=0&page_size=20
  2. Accept: application/json
复制代码
返回:
  1. GET https://api.vc.bilibili.com/link ... _num=0&page_size=20

  2. HTTP/1.1 200 OK
  3. Date: Sun, 21 Mar 2021 06:30:48 GMT
  4. Content-Type: application/json
  5. Transfer-Encoding: chunked
  6. Connection: keep-alive
  7. L: v
  8. X-Trace-Id: 29bd4f5ef5186679
  9. Http-Status-Code: 200
  10. Bili-Status-Code: 0
  11. Server: swoole-http-server
  12. Set-Cookie: l=v
  13. Expires: Sun, 21 Mar 2021 06:30:47 GMT
  14. Cache-Control: no-cache
  15. X-Cache-Webcdn: BYPASS from hw-sh3-webcdn-08

  16. {
  17.   "code": 0,
  18.   "msg": "success",
  19.   "message": "success",
  20.   "data": {
  21.     "total_count": 500,
  22.     "items": [
  23.       {
  24.         "user": {
  25.           "uid": 21690338,
  26.           "head_url": "https://i1.hdslb.com/bfs/face/b6a132c21e444401228099c8cc07edab810bc9db.jpg",
  27.           "name": "ZWPAN盼"
  28.         },
  29.         "item": {
  30.           "doc_id": 1085297,
  31.           "poster_uid": 21690338,
  32.           "pictures": [
  33.             {
  34.               "img_src": "https://i0.hdslb.com/bfs/album/2785de69bb019f85c88ee0d9681468c779e3950f.jpg",
  35.               "img_width": 3029,
  36.               "img_height": 9506,
  37.               "img_size": 6425
  38.             }
  39.           ],
  40.           "title": "108个小电视表情",
  41.           "category": "illustration",
  42.           "upload_time": 1512023535,
  43.           "already_liked": 0,
  44.           "already_voted": 0
  45.         }
  46.       },
  47. /////////////////////////////////////////
  48. /     {                                                                  /
  49. /     "_": "太多了,就不列举了"     /
  50. /     }                                                                  /
  51. /////////////////////////////////////////
  52.       ]
  53.   }
  54. }

  55. Response code: 200 (OK); Time: 490ms; Content length: 12879 bytes
复制代码
  • method:GET
  • params:

    • category
      图片的类型,选项如下

      • all:所有类型
      • illustration:插画
      • comic:漫画
      • draw:其他

    • type
      排名规则。选项如下:

      • hot:按热度排序
      • new:按时间排序

    • page_num
      页数,从0开始
    • page_size
      每页图片数

写爬虫
先在项目的根目录创建一个配置文件setting.py
  1. # picture settings

  2. PICTURE_MAX_PAGE = 20
  3. PICTURE_SLEEP_TIME = 0.5
  4. PICTURE_CATEGORY = "all"
  5. PICTURE_TYPE = "hot"
复制代码
  • PICTURE_MAX_PAGE
    爬的页数,每页20个
  • PICTURE_SELLP_TIME
    每爬一张图间隔的时间
  • PICTURE_CATEGORY
    要爬的图片的类型,选项如下

    • all:所有类型
    • illustration:插画
    • comic:漫画
    • draw:其他

  • PICTURE_TYPE
    排名规则。选项如下:

    • hot:按热度排序
    • new:按时间排序




打开bili/spider/picture.py

  1. 导入一些库
  2. import json
  3. import scrapy
  4. import time
  5. import setting
  6. from bili.items import BiliItem
复制代码
改写class PictureSpider(scrapy.Spider):
我们要先从https://h.bilibili.com/开始爬,从而免去设置Referer
  1. start_urls = ['https://h.bilibili.com/']
复制代码
再接着循环爬取刚才分析的链接即可,记住要构造请求并设置回调函数哦!
  1. def parse(self, response, **kwargs):
  2.     for i in range(setting.PICTURE_MAX_PAGE):
  3.         yield scrapy.Request(
  4.             'https://api.vc.bilibili.com/link_draw/v2/Doc/list?page_size=20'
  5.             '&type=' + setting.PICTURE_TYPE +
  6.             '&category=' + setting.PICTURE_CATEGORY +
  7.             '&page_num=' + str(i),
  8.             callback=self.picture_info,
  9.             dont_filter=True
  10.         )

  11. def picture_info(self, response, **kwargs):
  12.     data = json.loads(response.text)
  13.     for item in data["data"]["items"]:
  14.         img = BiliItem()
  15.         img["url"] = item["item"]["pictures"][-1]["img_src"]
  16.         img["title"] = item["item"]["title"]
  17.         img["id"] = item["item"]["doc_id"]
  18.         img["author"] = item["user"]["name"]
  19.         img["uid"] = item["user"]["uid"]
  20.         img["extension"] = img["url"].split('.')[-1]
  21.         yield img
  22.         time.sleep(setting.PICTURE_SLEEP_TIME)
复制代码
bili/spiders/picture.py完整代码
  1. import json
  2. import scrapy
  3. import time
  4. import setting
  5. from bili.items import BiliItem


  6. class PictureSpider(scrapy.Spider):
  7.     name = 'picture'
  8.     allowed_domains = ['bilibili.com']
  9.     start_urls = ['https://h.bilibili.com/']

  10.     def parse(self, response, **kwargs):
  11.         for i in range(setting.PICTURE_MAX_PAGE):
  12.             yield scrapy.Request(
  13.                 'https://api.vc.bilibili.com/link_draw/v2/Doc/list?page_size=20'
  14.                 '&type=' + setting.PICTURE_TYPE +
  15.                 '&category=' + setting.PICTURE_CATEGORY +
  16.                 '&page_num=' + str(i),
  17.                 callback=self.picture_info,
  18.                 dont_filter=True
  19.             )

  20.     def picture_info(self, response, **kwargs):
  21.         data = json.loads(response.text)
  22.         for item in data["data"]["items"]:
  23.             img = BiliItem()
  24.             img["url"] = item["item"]["pictures"][-1]["img_src"]
  25.             img["title"] = item["item"]["title"]
  26.             img["id"] = item["item"]["doc_id"]
  27.             img["author"] = item["user"]["name"]
  28.             img["uid"] = item["user"]["uid"]
  29.             img["extension"] = img["url"].split('.')[-1]
  30.             yield img
  31.             time.sleep(setting.PICTURE_SLEEP_TIME)
复制代码
下载图片
图片链接已经使用上面的picture_info()方法获取了,下面使用BiliPipeline管道下载图片
打开bili/pipelines.py
由于scrapy自带的图片下载器个人觉得使用起来太麻烦,这里直接用requests库就好
  1. import requests
  2. from os import path


  3. class BiliPipeline:
  4.     def process_item(self, item, spider):
  5.         name = str(item["id"]) + '.' + item["extension"]
  6.         res = requests.get(item["url"])
  7.         with open(path.join(path.join(path.abspath('.'), 'image'), name), 'wb') as file:
  8.             file.write(res.content)
  9.             print(name)
  10.         return item
复制代码
启用管道
打开bili/settings.py
找到以下内容并取消注释
  1. ITEM_PIPELINES = {
  2.    'bili.pipelines.BiliPipeline': 300,
  3. }
复制代码
在运行阶段为了减少不必要的log提示,可以在在里面添加
  1. LOG_LEVEL = "WARNING"
复制代码
本地启动爬虫测试启动爬虫
  1. # 切换到项目根目录
  2. scrapy crawl picture
复制代码
pycharm调试爬虫
点击右上角“编辑配置”
添加配置,选择python
配置如下
  • 脚本路径为python安装目录\Lib\site-packages\scrapy\cmdline.py
  • 参数为crawl 爬虫名
  • 工作目录为项目根目录

然后就可以愉快的打断点调试了   JetBrains NB
写workflows文件
在项目根目录创建:
  1. .github/workflows/blank.yml
复制代码
直接复制粘贴即可,有时间我会另写一篇入门GitHub Actions的文章,可能会鸽,咕咕咕。。。其实网上有很多这样的文章,例如:阮一峰的网络日志
  1. name: Spider

  2. on:
  3.   workflow_dispatch:

  4. jobs:
  5.   spider:
  6.     runs-on: ubuntu-latest
  7.     steps:
  8.     - name: checkout
  9.       uses: actions/checkout@master

  10.     - name: 'Set up Python'
  11.       uses: actions/setup-python@v1
  12.       with:
  13.         python-version: 3.7

  14.     - name: Run a single-line script
  15.       run: |
  16.         pip install requests
  17.         pip install lxml
  18.         pip install scrapy
  19.         scrapy crawl picture

  20.     - name: Upload artifact
  21.       uses: actions/upload-artifact@master
  22.       with:
  23.         name: img
  24.         path: image
复制代码
部署到GitHub Actions
在Github上新建仓库
将代码推送到该仓库里
Git三部曲:
  1. git add .                     # 添加
  2. git commit -m "init"        # 提交
  3. git push                        # 推送
复制代码
打开GitHub仓库网页
依次点击:
等待一小会,不出意外的话,爬虫的结果就显示出来了,点击下载即可
illust_81689532_20201227_014258.png

吐槽一句:1M的图太小啦,还要我传到自己的OSS上( ^ω^)




举报

该用户从未签到

10

主题

51

回帖

404

积分

Judgement

积分
404
不出所料,对MarkDown和代码块的支持惨不忍睹:L:L:L

举报

  • TA的每日心情

    2024-12-20 08:42
  • 签到天数: 1 天

    [LV.1]初来乍到

    69

    主题

    82

    回帖

    1093

    积分

    造物主

    站长

    积分
    1093
    QQ
    好耶,这比阿方厉害多了,
    世间漫随流水,算来一梦浮生

    举报

  • TA的每日心情
    郁闷
    2024-11-22 16:10
  • 签到天数: 3 天

    [LV.2]偶尔看看I

    19

    主题

    75

    回帖

    2168

    积分

    Judgement

    世界第一公主殿下

    积分
    2168
    QQ
    以最初的声音,追寻未来的梦

    举报

    该用户从未签到

    6

    主题

    36

    回帖

    459

    积分

    LV.2

    积分
    459
    QQ

    举报

    该用户从未签到

    0

    主题

    2

    回帖

    18

    积分

    LV.1

    积分
    18
    非常厉害的样子

    举报

    该用户从未签到

    10

    主题

    87

    回帖

    416

    积分

    版主

    积分
    416
    QQ
    np!

    举报

    该用户从未签到

    10

    主题

    87

    回帖

    416

    积分

    版主

    积分
    416
    QQ
    啊对了,请问一下,这个是python吗?我想学习这个,但是不知道该怎么学……

    举报

    您需要登录后才可以回帖 登录 | 注册SCIFIFANS!

    本版积分规则