1. 项目名称问题
在使用的时候遇到过一个问题,在初始化scrapy startproject tutorial
的时候,如果使用了一些特殊的名字,如:test
, fang
等单词的话,通过get_project_settings
方法获取配置的时候会出错,改成tutorial
或一些复杂的名字的时候不会
|
这是一个bug,在github上有提到:https://github.com/scrapy/scrapy/issues/428,但貌似没有完全修复,修改一下名字就好了(当然scrapy.cfg
和settings.py
里面也需要修改)
2. 为每个pipeline配置spider
上面我们是在settings.py里面配置pipeline,这里的配置的pipeline会作用于所有的spider,我们可以为每一个spider配置不同的pipeline,设置Spider
的custom_settings
对象
|
3. 获取提取链接的节点信息
通过LinkExtractor提取的scrapy.Link
默认不带节点信息,有时候我们需要节点的其他attribute属性,scrapy.Link
有个text
属性保存从节点提取的text
值,我们可以通过修改lxmlhtml._collect_string_content
变量为etree.tostring
,这样可以在提取节点值就变味渲染节点scrapy.Link.text
,然后根据scrapy.Link.text
属性拿到节点的html,最后提取出我们需要的值
|
4. 从数据库中读取urls
有时候我们已经把urls下载到数据库了,而不是在start_urls里配置,这时候可以重载spider的start_requests
方法
|
我们还可以在Request添加元数据,然后在response中访问
|
5. 如何进行循环爬取
有时候我们需要爬取的一些经常更新的页面,例如:间隔时间为2s,爬去一个列表前10页的数据,从第一页开始爬,爬完成后重新回到第一页
目前的思路是,通过parse方法迭代返回Request进行增量爬取,由于scrapy默认由缓存机制,需要修改
6. 关于去重
scrapy默认有自己的去重机制,默认使用scrapy.dupefilters.RFPDupeFilter
类进行去重,主要逻辑如下
|
默认的去重指纹是sha1(method + url + body + header),这种方式并不能过滤很多,例如有一些请求会加上时间戳的,基本每次都会不同,这时候我们需要自定义过滤规则
|
配置setting
|
7. 如何在Pipeline中处理不同的Item
scrapy所有的迭代出来的的Item都会经过所有的Pipeline,如果需要处理不同的Item,只能通过isinstance()
方法进行类型判断,然后分别进行处理,暂时没有更好的方案
8. url按顺序执行
我们可以通过Request的priority控制url的请求的执行顺序,但由于网络请求的不确定性,不能保证返回也是按照顺序进行的,如果需要进行逐个url请求的话,吧url列表放在meta对象里面,在response的时候迭代返回下一个Request对象到调度器,达到顺序执行的目的,暂时没有更好的方案
9. Scrapy "Filtered duplicate request" 结束运行
yield scrapy.Request(
info_url,
cookies=self.cookie,
callback=self.parse_info,
dont_filter=True,(添加这一行)
meta={
'item': item,
'date': meta_data['date'],
'weibo_id': meta_data['weibo_id']
}
)
10.scrapy设置cookie失效不管用
# 如果使用自定义cookie就把COOKIES_ENABLED设置为True # 如果使用settings的cookie就把COOKIES_ENABLED设置为False COOKIES_ENABLED = True