简介
Scrapy是一个为了爬取网站数据,提取结构性数据而编写的应用框架。 可以应用在包括数据挖掘,信息处理或存储历史数据等一系列的程序中。
其最初是为了 页面抓取 (更确切来说, 网络抓取 )所设计的, 也可以应用在获取API所返回的数据或者通用的网络爬虫。
安装
环境: Mac, Python 3.7
使用 pip 安装命令:
1
pip install scrapy
创建 Scrapy 项目
-
命令行 cd 到代码存储路径下, 例如桌面上新建的文件夹 Scrapy 目录
1
cd desktop/Scrapy
-
使用 scrapy 命令创建项目:
1
scrapy startproject tutorial
等待执行结束, 一般会有提示进行下一步创建爬虫操作.
改命令还会创建如下 tutorial 目录:
1 2 3 4 5 6 7 8 9 10 11
tutorial/ scrapy.cfg tutorial/ __init__.py __pycache__ items.py pipelines.py settings.py spiders/ __init__.py __pycache__
-
创建爬虫文件
安装第二步提示, 分别执行以下命令:
1 2
cd tutorial scrapy genspider Baidu baidu.com
可以在 spiders 目录下看到新生成一个 JanShu.py 文件
使用 PyCharm 或者 VSCode 将项目打开, 可以看到 Baidu.py 文件中有一个 BaiduSpider 类, 且继承自 scrapy.Spider, 其中的属性如下:
- name: 用于区别Spider。 该名字必须是唯一的,您不可以为不同的Spider设定相同的名字。
- start_urls: 包含了Spider在启动时进行爬取的url列表。 因此,第一个被获取到的页面将是其中之一。 后续的URL则从初始的URL获取到的数据中提取。
- parse(self, response) 是spider的一个方法。 被调用时,每个初始URL完成下载后生成的 Response 对象将会作为唯一的参数传递给该函数。 该方法负责解析返回的数据(response data),提取数据(生成item)以及生成需要进一步处理的URL的 Request 对象。
-
开启爬虫任务
这里需要进入项目的根目录, 也就是第二步最开始的tutorial目录下.
开启命令:
1
scrapy crawl Baidu
之后可以看到命令行控制台输出响应, 可以看到返回状态码200.
由于scrapy 默认遵从爬虫爬取规则, 所以也会看到:
DEBUG: Forbidden by robots.txt: <GET http://baidu.com/>
可点击查看http://baidu.com/robots.txt
下面会继续通过实例介绍 Scrapy 如何使用.
也推荐阅读 Scrapy 文档
实例
我们以简书为例, 来爬取首页中的文章标题, 作者, 缩略图等.
-
新建爬虫 JianShuSpider
1
scrapy genspider JianShu www.jianshu.com
-
声明Item
Item使用简单的class定义语法以及 Field 对象来声明。
1 2 3 4 5 6 7 8 9 10 11 12
import scrapy class TutorialItem(scrapy.Item): # define the fields for your item here like: # name = scrapy.Field() # 文章标题 title = scrapy.Field() # 作者 author = scrapy.Field() # 图片 img = scrapy.Field()
-
设置UA(可选)
在 settings.py 中修改
1 2
# settings.py USER_AGENT = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Safari/537.36'
如果要设置随机值, 可以如下, 附上一些 UA:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
# settings.py USER_AGENTS_LIST = [ 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Safari/537.36', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_3) AppleWebKit/536.5 (KHTML, like Gecko) Chrome/19.0.1084.54 Safari/536.5', "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; AcooBrowser; .NET CLR 1.1.4322; .NET CLR 2.0.50727)", "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0; Acoo Browser; SLCC1; .NET CLR 2.0.50727; Media Center PC 5.0; .NET CLR 3.0.04506)", "Mozilla/4.0 (compatible; MSIE 7.0; AOL 9.5; AOLBuild 4337.35; Windows NT 5.1; .NET CLR 1.1.4322; .NET CLR 2.0.50727)", "Mozilla/5.0 (Windows; U; MSIE 9.0; Windows NT 9.0; en-US)", "Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Win64; x64; Trident/5.0; .NET CLR 3.5.30729; .NET CLR 3.0.30729; .NET CLR 2.0.50727; Media Center PC 6.0)", "Mozilla/5.0 (compatible; MSIE 8.0; Windows NT 6.0; Trident/4.0; WOW64; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; .NET CLR 1.0.3705; .NET CLR 1.1.4322)", "Mozilla/4.0 (compatible; MSIE 7.0b; Windows NT 5.2; .NET CLR 1.1.4322; .NET CLR 2.0.50727; InfoPath.2; .NET CLR 3.0.04506.30)", "Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN) AppleWebKit/523.15 (KHTML, like Gecko, Safari/419.3) Arora/0.3 (Change: 287 c9dfb30)", "Mozilla/5.0 (X11; U; Linux; en-US) AppleWebKit/527+ (KHTML, like Gecko, Safari/419.3) Arora/0.6", "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.2pre) Gecko/20070215 K-Ninja/2.1.1", "Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN; rv:1.9) Gecko/20080705 Firefox/3.0 Kapiko/3.0", "Mozilla/5.0 (X11; Linux i686; U;) Gecko/20070322 Kazehakase/0.4.5", "Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.0.8) Gecko Fedora/1.9.0.8-1.fc10 Kazehakase/0.5.6", "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/535.11 (KHTML, like Gecko) Chrome/17.0.963.56 Safari/535.11", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_3) AppleWebKit/535.20 (KHTML, like Gecko) Chrome/19.0.1036.7 Safari/535.20", "Opera/9.80 (Macintosh; Intel Mac OS X 10.6.8; U; fr) Presto/2.9.168 Version/11.52", "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/536.11 (KHTML, like Gecko) Chrome/20.0.1132.11 TaoBrowser/2.0 Safari/536.11", "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.1 (KHTML, like Gecko) Chrome/21.0.1180.71 Safari/537.1 LBBROWSER", "Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; .NET4.0C; .NET4.0E; LBBROWSER)", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; QQDownload 732; .NET4.0C; .NET4.0E; LBBROWSER)", "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/535.11 (KHTML, like Gecko) Chrome/17.0.963.84 Safari/535.11 LBBROWSER", "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.1; WOW64; Trident/5.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; .NET4.0C; .NET4.0E)", "Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; .NET4.0C; .NET4.0E; QQBrowser/7.0.3698.400)", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; QQDownload 732; .NET4.0C; .NET4.0E)", "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; Trident/4.0; SV1; QQDownload 732; .NET4.0C; .NET4.0E; 360SE)", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; QQDownload 732; .NET4.0C; .NET4.0E)", "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.1; WOW64; Trident/5.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; .NET4.0C; .NET4.0E)", "Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.1 (KHTML, like Gecko) Chrome/21.0.1180.89 Safari/537.1", "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.1 (KHTML, like Gecko) Chrome/21.0.1180.89 Safari/537.1", "Mozilla/5.0 (iPad; U; CPU OS 4_2_1 like Mac OS X; zh-cn) AppleWebKit/533.17.9 (KHTML, like Gecko) Version/5.0.2 Mobile/8C148 Safari/6533.18.5", "Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:2.0b13pre) Gecko/20110307 Firefox/4.0b13pre", "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:16.0) Gecko/20100101 Firefox/16.0", "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.11 (KHTML, like Gecko) Chrome/23.0.1271.64 Safari/537.11", "Mozilla/5.0 (X11; U; Linux x86_64; zh-CN; rv:1.9.2.10) Gecko/20100922 Ubuntu/10.10 (maverick) Firefox/3.6.10" ]
移动端UA标识:
1 2 3 4 5 6 7 8 9 10 11 12
MOBILE_USER_AGENTS_LIST = [ "Mozilla/5.0 (iPhone; CPU iPhone OS 9_1 like Mac OS X) AppleWebKit/601.1.46 (KHTML, like Gecko) Version/9.0 Mobile/13B137 Safari/601.1", "Mozilla/5.0 (iPhone; CPU iPhone OS 9_1 like Mac OS X) AppleWebKit/601.1 (KHTML, like Gecko) CriOS/74.0.3729.131 Mobile/13B143 Safari/601.1.46", "Mozilla/5.0 (iPad; CPU OS 9_1 like Mac OS X) AppleWebKit/601.1 (KHTML, like Gecko) CriOS/74.0.3729.131 Mobile/13B143 Safari/601.1.46", "Mozilla/5.0 (iPhone; CPU iPhone OS 8_3 like Mac OS X) AppleWebKit/600.1.4 (KHTML, like Gecko) FxiOS/1.0 Mobile/12F69 Safari/600.1.4", "Mozilla/5.0 (iPad; CPU iPhone OS 8_3 like Mac OS X) AppleWebKit/600.1.4 (KHTML, like Gecko) FxiOS/1.0 Mobile/12F69 Safari/600.1.4", "Mozilla/5.0 (iPad; CPU OS 9_1 like Mac OS X) AppleWebKit/601.1.46 (KHTML, like Gecko) Version/9.0 Mobile/13B137 Safari/601.1", "Mozilla/5.0 (iPhone; CPU iPhone OS 9_1 like Mac OS X) AppleWebKit/601.1.46 (KHTML, like Gecko) Version/9.0 Mobile/13B137 Safari/601.1", "UCWEB/2.0 (iPad; U; CPU OS 7_1 like Mac OS X; en; iPad3,6) U2/1.0.0 UCBrowser/9.3.1.344", "Mozilla/5.0 (iPhone; CPU iPhone OS 11_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/11.0 Mobile/15E148 Safari/604.1", ]
之后在 middlewares.py 中修改 TutorialSpiderMiddleware 类的init方法:
1 2 3 4 5
# middlewares.py class TutorialSpiderMiddleware(object): def __init__(self, user_agent=""): self.user_agent = user_agent
以及 TutorialDownloaderMiddleware 类中的方法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
# middlewares.py class TutorialDownloaderMiddleware(object): def __init__(self, user_agent): self.user_agent = user_agent @classmethod def from_crawler(cls, crawler): # This method is used by Scrapy to create your spiders. s = cls(user_agent=crawler.settings.get("USER_AGENTS_LIST")) crawler.signals.connect(s.spider_opened, signal=signals.spider_opened) return s def process_request(self, request, spider): agent = random.choice(self.user_agent) request.headers["User-Agent"] = agent
这里有个问题, 就是在 process_request() 方法中设置 UA 时, 使用
request.headers.setdefaults()
可能会无效. 这里可以查看这篇文章,1
>这是因为 request.headers.setdefault() 方法中 . setdefault 方法意味着 : 如果键不存在于字典中,将会添加键并将值设为默认值。如果存在,则不添加 。 可参考 [文档](https://www.runoob.com/python/att-dictionary-setdefault.html){:target="_blank"}, 因为系统的 UserAgentMiddleware 已经添加了 User-Agent ,所以我们这里添加失败.
-
防爬处理(可选)
首先设置不遵循反爬虫规则, 一般网站都有设置, 可参考百度 (http://baidu.com/robots.txt)
这里我们修改 settings.py
1
ROBOTSTXT_OBEY = False
设置延时, 延时能解决大部分反爬问题.
1 2
# 可设置随机值 DOWNLOAD_DELAY = 1
也可以在 middlewares.py中 TutorialDownloaderMiddleware 类的 process_request() 方法设置
1 2 3 4 5 6
# middlewares.py class TutorialDownloaderMiddleware(object): def process_request(self, request, spider): deley = random.choice([0.5, 0.6, 0.7, 0.8, 1, 1.1, 1.2]) time.sleep(deley)
还有就是设置代理, 一般需要收费, 也有免费的, 但是不太好使.
言归正传. 在 middlewares.py 增加:
1 2 3 4 5 6
# middlewares.py class HttpbinProxyMiddleware(object): def process_request(self, request, spider): pro_addr = requests.get('http://127.0.0.1:5000/get').text request.meta['proxy'] = 'http://' + pro_addr
然后回到 settings.py, 修改:
1 2 3 4
# settings.py DOWNLOADER_MIDDLEWARES = { 'httpbin.middlewares.HttpbinProxyMiddleware': 543, }
-
自定义过滤规则(可选)
新建 httpdupefilters.py 文件, 如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
# httpdupefilters.py from scrapy.dupefilters import BaseDupeFilter from scrapy.utils.request import request_fingerprint class HttpDupefilters(BaseDupeFilter): def __init__(self): #初始化visited_fd为一个集合[也可以放到redis中] self.visited_fd = set() @classmethod def from_settings(cls, settings): return cls() def request_seen(self, request): ''' :param request: 请求url[进行类似md5加密的操作] http://www.baidu.com?su=123&456 http://www.baidu.com?su=456&123 以上两个的伪MD5是一样的 伪MD5值得方法是request_fingerprint :return: ''' print('=======过滤=======') fd = request_fingerprint(request=request) # 如果路径在visited_fd中返回True if fd in self.visited_fd: print('已过滤:', request) return True #添加到集合中 self.visited_fd.add(fd) def open(self): #can return deferred print('=====开始=====') def close(self, reason): #can return a deferred print('=====结束=====') def log(self, request, spider): #log that a request has been filterd print('=====日志=====') spider.crawler.stats.inc_value('dupefilter/filtered', spider=spider)
然后回到 settings.py 中, 编辑:
1 2
# settings.py DUPEFILTER_CLASS = 'tutorial.httpdupefilters.HttpDupeFilter'
然后配合爬虫文件中 parse() 方法使用:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
# JianShu.py import scrapy from scrapy.http import Request from tutorial.items import TutorialItem class JianshuSpider(scrapy.Spider): name = 'JianShu' allowed_domains = ['jianshu.com'] start_urls = ['http://www.jianshu.com/'] def parse(self, response): meta = response.meta['item'] print(meta, response.body) items = [] item = TutorialItem() item.title = '' item.author = '' item.img = '' item.url = '' for item in items: yield Request(item.url, callback=self.parse_content, meta={"item": 'item'}, dont_filter=False, ) return items def parse_content(self, response): meta = response.meta['item'] print(meta, response.body) pass
可以在控制台看到日志输出多了一行输出: ` ‘dupefilter/filtered’: 696,`
-
在请求前处理 start_urls 参数, 或者传参
重写父类 start_requests() 方法:
1 2 3 4 5 6 7 8 9 10 11 12 13
# JianShu.py class JianshuSpider(scrapy.Spider): name = 'JianShu' allowed_domains = ['jianshu.com'] start_urls = ['http://www.jianshu.com/'] # 重写父类的方法, 处理 start_urls 参数等 def start_requests(self): yield Request('http://www.jianshu.com/', callback=self.parse, meta={"item": 'item'}, dont_filter=False, )
-
保存数据
此处以 MongoDB 为例, Monogo安装步骤, 参考文档: https://docs.mongodb.com/
Python 中使用的库为 pymongo, 安装步骤, 参考文档: http://api.mongodb.com/python/current/index.html
修改 settings.py 文件:
1 2 3
# settings.py MONGO_URI = 'mongodb://localhost:27017' MONGO_DB = "tutorial"
找到 pipelines.py, 编辑内容如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62
# pipelines.py import pymongo class TutorialPipeline(object): def __init__(self, mongo_uri, mongo_db): # self.file = codecs.open('item.json', 'wb', encoding='utf-8') self.mongo_uri = mongo_uri self.mongo_db = mongo_db @classmethod def from_crawler(cls, crawler): ''' scrapy为我们访问settings提供了这样的一个方法,这里, 我们需要从settings.py文件中,取得数据库的URI和数据库名称 ''' return cls( mongo_uri = crawler.settings.get('MONGO_URI'), mongo_db = crawler.settings.get('MONGO_DB'), ) def open_spider(self, spider): ''' 爬虫一旦开启, 就会实现这个方法, 链接到数据库 ''' self.client = pymongo.MongoClient(self.mongo_uri) self.db = self.client[self.mongo_db] def close_spider(self, spider): ''' 爬虫一旦关闭,就会实现这个方法,关闭数据库连接 ''' self.client.close() def process_item(self, item, spider): ''' 每个实现保存的类里面必须要有这个方法, 且名字固定, 用来具体实现怎么保存 ''' # if not item['title']: # # return item # print('item不存在title:',item) ''' SQLServer 更新数据库 ''' if not item['description']: return item ''' MongoDB 更新数据库 ''' # 本地测试 MongoDB data = { 'title': item['title'], 'author': item['author'], 'img': item['img'], 'url': item['url'], } # table = self.db[spider.name] # # table.insert_one(data) table.update({'href': item['href']}, data, True); return item
使用文件格式保存, 可使用如下方式:
1 2
line = json.dumps(dict(item), ensure_ascii=False) + '\n' self.file.write(line)
- 部分由js动态渲染的网页抓取为空时, 可以采用scapy-splash框架, 下面介绍下如何使用scrapy-splash框架抓取动态渲染的页面
Scrapy-Splash
什么是Scrapy-Splash?
它是一个JavaScript渲染服务, 由Python实现的一个HTTP API的轻量级浏览器, 同时使用Twisted和QT, Twisted(QT)用来让服务具有异步处理能力,以发挥webkit的并发能力, 所以性能上会比Selenium会好许多.
特点:
- 并行处理多个网页
- 得到HTML结果以及(或者)渲染成图片
- 关掉加载图片或使用 Adblock Plus规则使得渲染速度更快
- 使用JavaScript处理网页内容
- 使用Lua脚本
- 能在Splash-Jupyter Notebooks中开发Splash Lua scripts
- 能够获得具体的HAR格式的渲染信息
安装:
scrapy-splash使用的是Splash HTTP API, 所以需要一个splash instance, 一般采用docker运行splash, 首先需要先安装Docker
I. Mac环境下安装
[1] 安装并启动Docker
点击下载 Docker for Mac
[2] 拉取 splash 镜像资源
1
$ sudo docker pull scrapinghub/splash
如果Docker获取镜像报错 docker: Error response from daemon, 可使用Docker国内镜像.
修改方法:
右键点击桌面顶栏的 docker 图标,选择 Preferences ,在 Daemon 标签(Docker 17.03 之前版本为 Advanced 标签)下的 Registry mirrors 列表中加入下面的镜像地址:
http://141e5461.m.daocloud.io
点击 Apply 应用, 然后点击 Restart 使设置生效
[3] 开启容器
1
$ sudo docker run -p 8050:8050 scrapinghub/splash
运行成功, 可在浏览器中输入localhost:8050
验证.
II. Linux CentOS环境安装
[1] 安装并启动Docker
安装
1
$ sodu yum install docker
启动
1
$ sudo service docker start
该过程可能需要几分钟时间,
[2] 拉取 splash 镜像资源
1
$ sudo docker pull scrapinghub/splash
[3] 开启容器
1
$ sudo docker run -p 8050:8050 scrapinghub/splash
使用
[1] 安装Scrapy-Splash模块
1
$ pip install scrapy-splash
[2] 修改配置信息:
找到Scrapy爬虫项目的settings.py文件, 修改配置信息:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# 添加splash服务地址
SPLASH_URL = 'http://localhost:8050'
# 启用SplashDeduplicateArgsMiddleware
SPIDER_MIDDLEWARES = {
'scrapy_splash.SplashDeduplicateArgsMiddleware': 100,
}
# 将splash middleware添加到DOWNLOADER_MIDDLEWARE中:
DOWNLOADER_MIDDLEWARES = {
'scrapy_splash.SplashCookiesMiddleware': 723,
'scrapy_splash.SplashMiddleware': 725,
'scrapy.downloadermiddlewares.httpcompression.HttpCompressionMiddleware': 810
}
# 使用splash默认过滤规则, 也可使用自定义规则
DUPEFILTER_CLASS = 'scrapy_splash.SplashAwareDupeFilter'
# 使用splash缓存
HTTPCACHE_STORAGE = 'scrapy_splash.SplashAwareFSCacheStorage'
[3] 修改爬虫文件MySpider.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
# -*- coding: utf-8 -*-
from scrapy import Spider, Request
from scrapy_splash import SplashRequest
class MySpider(scrapy.Spider):
name = 'MySpider'
# allowed_domains = ['']
url = 'http://m.2958.cn/'
# start request
def start_requests(self):
# splash lua script
splash_args = {"lua_source": """
--splash.response_body_enabled = true
splash.private_mode_enabled = false
splash:set_user_agent("Mozilla/5.0 (iPhone; CPU iPhone OS 11_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/11.0 Mobile/15E148 Safari/604.1")
assert(splash:go("%s"))
splash:wait(1)
return {html = splash:html()}
""" % (self. url)}
# Scrapy 方法
# yield Request(self.url, callback=self.parse)
# Scrapy-Splash 方法
yield SplashRequest(self.url, callback=self.parse, endpoint='run', args= splash_args)
# parse the html content
def parse(self, response):
# 此处可对比下使用Scrapy的Request和Scrapy-Splash的SplashRequest获取到response.body的不同
print(response.body)