互联网中众多的 scrapy 教程模板,都是爬取 下一页$\rightarrow$下一页形式的,很少有 父级$\rightarrow$子级 的说明。
本文介绍一些使用 scrapy 爬取三级网页的注意事项。
逐级别传递 item
如何将 item 的信息,从父级传送到子级,是多级别爬取的最重要部分。
Scrapy 用 scrapy.Request
发起请求时,可以带上 meta={'item': item}
,把之前已收集到的信息传递到新请求里。
在新请求里用 item = response.meta('item')
接受过来,item 就可以继续添加新的收集的信息了。
注意:meta字段的方法是浅拷贝,并非深拷贝,(可参考官方文档),所以如果 item 有多个字段时,要么在meta中多字段表示,要么使用深拷贝方法。
1# 使用 scrapy 在多个 parse 中自上而下逐级传递 item 的方法
2# method 1
3import copy
4
5yield scrapy.Request(
6 url=next_url,
7 meta={
8 'item': copy.deepcopy(item_before)
9 },
10 dont_filter=True,
11 callback=self.next_parse
12)
13
14# method 2
15yield scrapy.Request(
16 url=next_url,
17 meta={
18 'thing1': thing1_before,
19 'thing2': thing2_before
20 },
21 dont_filter=True,
22 callback=self.next_parse
23)
是否需要进行 url去重操作?
如果二级页面的 url 是根据某内容来定义 url路径 的,因此会存在很多重复的 二级url,需要不去重操作。
去重机制:
scrapy.Request()
的参数dont_filter
默认是False
(去重)。
每 yield 一个scrapy.Request()
,就将 url参数 与调度器内已有的 url 进行比较,如果存在相同 url 则默认不入队列,如果没有相同的 url 则入队列,
如果想要实现不去重效果,需要将dont_filter
改为True
来自参考链接:spider爬取多级url
scrapy selector 的 extract 与 extract_first 方法
extract
以列表形式(记此列表为a
)返回选择器中的 data 字段,extract_first
则返回上述列表a
中的第一个元素(多为字符串)- 通常
extract
得到的列表中,只有一个元素,所以往往用extract_first
即可。
但若extract
得到的列表中有多个元素,则需要使用''.join(a)
得到具体的字符串信息。 ' xxx '.strip()
可以用于去掉头尾空白字符
编写 pipeline 注意事项
- 首先需要在设置中启动pipeline,才可以有效果
- mkdir创建单级目录,makedirs创建多级目录
- 需要首先
dict(item)
- 打开文件时
- w 只可以写文件
- w+ 可读可写,打开后立即清空
- r 只可以读文件
- r+ 可读可写
- encoding 保存中文必选
- 写json时,注意使用
"
而非'
json.dump(text, f, ensure_ascii=False, indent=4)
可保存中文,并格式化json
启用 scrapy 日志功能
详细见参考链接
版权声明:本文遵循 CC BY-SA 4.0 版权协议,转载请附上原文出处链接和本声明。
Copyright statement: This article follows the CC BY-SA 4.0 copyright agreement. For reprinting, please attach the original source link and this statement.