7.scrapy管道的使用
7.1 pipeline中常用的方法
- process_item(self,item,spider):
- 管道类中必须有的函数
- 实现对item数据的处理
- 必须return item
- open_spider(self, spider):在爬虫开启的时候仅执行一次
- close_spider(self, spider):在爬虫关闭的时候仅执行一次
7.2 在settings中能够开启多个管道,为什么需要开启多个?
- 1.不同的pipeline可以处理不同爬虫的数据,通过spider.name属性来区分
- 2.不同的pipeline能够对一个或多个爬虫进行不同的数据处理的操作,比如一个进行数据清洗,一个进行数据的保存
- 3.同一个管道类也可以处理不同的爬虫的数据,通过spider.name属性来区分
7.3 pipeline使用注意点
-
1.使用之前需要在settings中开启
-
2.pipeline在setting中键表示位置(即pipeline在项目中的位置可以自定义),值表示距离引擎的远近,越近越会优先经过:权重值小的优先执行
-
3.有多个pipeline的时候,process_item方法必须return item,否则后一个pipeline取到的数据为None值
-
4.pipeline中process_item的方法必须有,否则item没有办法接受和处理
-
5.proecess_item方法接受item和spider,其中spider表示当前传递item过来的spider
8.scrapy的crawlspider爬虫
8.1 srawlspider是什么
思路:
- 1.从response中提取所有的满足规则的url地址
- 2.自动的构造自己reqeusts请求,发送给引擎
对应的crawlspider就可以实现上述需求,能够匹配满足条件的url地址,组装成Reqeust对象后自动发送给引擎,同时能够指定callback函数
即:crawlspider爬虫可以按照规则自动获取连接
8.2 创建crawlspider爬虫并观察爬虫的默认内容
-
1.创建crawlspider爬虫:
scrapy genspider -t crawl job 163.com
-
2.spider中默认生成的内容如下:
import scrapy # 链接提取器 from scrapy.linkextractors import LinkExtractor # 爬虫类 规则 from scrapy.spiders import CrawlSpider, Rule class JobCrawlSpider(CrawlSpider): name = 'job_crawl' allowed_domains = ['163.com'] start_urls = ['http://163.com/'] # 存放链接处理规则 rules = ( # 链接处理规则对象,LinkExtractor用于定义提取规则,callback用于设定链接提取规则提取的链接对应的响应由谁处理 Rule(LinkExtractor(allow=r'Items/'), callback='parse_item', follow=True), ) # 没有parse方法 def parse_item(self, response): item = {} #item['domain_id'] = response.xpath('//input[@id="sid"]/@value').get() #item['name'] = response.xpath('//div[@id="name"]').get() #item['description'] = response.xpath('//div[@id="description"]').get() return item
-
3.和普通的scarapy.spider的区别
在crawlspider爬虫中,没有parse函数
-
重点在rules中:
- 1.rules是一个元素或者列表,包含的是Rule对象
- 2.Rule表示规则,其中包含LinkExtractor,callback等参数
- 3.LinkeExtractor,链接提取器,可以通过正则或者是xpath来进行url地址的匹配
- 4.callback,表示经过链接提取出来的url地址响应的回调函数,可以没有,没有表示响应不会进行回调函数的处理
- 5.follow,链接提取器的url地址对应的响应是否还会继续被rules中的规则进行提前,True表示会,False表示不会
-
4.crawlspider使用的注意点:
- 1.连接提取其LinkExtractor中的allow对应的正则表达式匹配的是href属性的值
- 2.处理用命令scrapy genspider -t scawl <爬虫名> <allowed_demail> 创建一个crawlspider的模板,也可以手动创建
- 3.crawlspider中不能再有以parse为名的数据提取方法,该方法被crawlspider用来实现基础url提取等功能
- 4.Rule对象中的LinkeExtracotr为固定参数,其他callback/follow为可选参数
- 5.不指定callback切follow为True的情况下,满族rules中规则的url还会被继续提取和请求
- 6.如果一个被提取的url满足多个Rule,那么会从rules中选择一个满族匹配条件的Rule执行
-
5.了解crawlspder其他知识点
- 链接提取器LinkExtractor的更多常见参数
- allow:满族括号中的’re’表达式的url会被提取,如果为空,则全部提取
- deny:满族括号中的’re’表达式的url不会被提取,和优先级高于allow
- allow_domains:会被提取的链接的domains(url)范围,如[‘hr.tencent.com’,‘baidu.com’]
- deny_domains:不会被提取的链接的domains(url范围)
- restrict_xpaths:使用xpath规则进行匹配,和allow共同过滤url,即xpath满足的范围内的url地址会被提取,如:restrict_xpath =’//div[@class=‘info]’
- Rule常见参数
- 3.LinkeExtractor,链接提取器,可以通过正则或者是xpath来进行url地址的匹配
- 4.callback,表示经过链接提取出来的url地址响应的回调函数,可以没有,没有表示响应不会进行回调函数的处理
- 5.follow,链接提取器的url地址对应的响应是否还会继续被rules中的规则进行提前,True表示会,False表示不会
- process_links:当链接提取器LinkExtractor获取到链接列表的时候调用该参数指定的方法,这个自定义方法可以用来过滤url,且这个方法执行后才会执行callback指定的方法
- 链接提取器LinkExtractor的更多常见参数
9.scrapy中间件的使用
9.1 scrapy中间件的分类和作用
- 根据scrapy运行流程中所在的位置不同分为:
- 下载中间件
- 爬虫中间件
- 根据scrapy中间件的作用:预处理reqeust和response对象
- 对header以及cookie进行更换和处理
- 使用代理ip等
- 对请求进行定制化操作
但在scrapy默认的情况下,两种中间件都在middlewares.py一个文件中
爬虫中间件使用方法和下载中间件相同,且功能重复,通常使用下载中间件
9.2 下载中间件的使用方法:
Downloader Middlewares默认的方法:
- process_request(self, request, spider):
- 1.当每个reqeust通过下载中间件时,该方法被调用
- 2.返回None值:没有return也是返回None,该reqeust对象传递给下载器,或通过引擎传递给其他权重值低的process_reqeusts方法
- 3.返回Response对象:不再请求,把response返回给引擎
- 4.返回Request对象:把request对象通过引擎交给调度器,此时将不通过其他权重值底的process_request方法
- process_response(self, request, response ,spider)
- 1.当下载器完成http请求,传递响应给引擎的时候调用
- 2.返回Response:通过引擎交给爬虫处理或交给权重更低的其他下载中间件的process_response方法
- 3.返回Request:通过引擎交给调度器继续请求,此时将不再通过其他权重值低的process_request方法
- 在settings.py中配置开启中间件,权重值越小越优先执行
11.随机请求头
-
1.在网上找一堆请求头
-
2.在settings.py文件中,设置参数USER_AGENT_LIST=[‘一堆请求头’]
-
3.在middlewares.py文件中导入这个 USER_AGENT_LIST
-
4.然后在middlewares.py文件中定义一个中间件类
-
class RandomUserAgent(object): def process_request(self, request, spider): ua = random.choice(USER_AGENT_LIST) request.headers['Usera-Agent'] = ua
-
-
5.在settings.py文件中DOWNLOADER_MIDDLEWARES 把新的类名更改上
-
6.重新运行
12.随机IP代理
12.1 代理ip的使用
-
思路分析
- 1.代理添加的位置:request.meta中添加proxy字段
- 2.获取一个代理ip,赋值给request.meta[‘proxy’]
- 代理池中随机选择代理ip
- 代理ip的webapi发送请求获取一个代理ip
-
使用
-
1.在settings.py文件中添加PROXY_LIST=[’ip_port‘:“ip地址:端口号”,‘user_passwd’:“账号”:"“密码”]
-
2.在middlewares.py文件中新建类
-
class RandomProxy(object): def process_request(self,request,spider): proxy = random.choice(PROXY_LIST) if 'user_passwd' in proxy: # 对账号密码进行加密 b64_up = base64.b64encode(proxy['user_passwd'].encode()) # 设置认证 request.headers['Proxy-Authorization'] = 'Basic ' + b64_up.decode() # 设置代理 request.meta['proxy'] = proxy['ip_port'] else: # 设置代理 request.meta['proxy'] = proxy['ip_port']
-
-
3.在settings.py文件中DOWNLOADER_MIDDLEWARES 把新的类名更改上
-
4.重新运行
-
13.在中间件中使用selenium——动态渲染
- 1.middlewares.py
class SeleniumMiddleware(objcet):
def process_request(self, request, spider):
url = request.url
if 'daydata' in url:
driver webdriver.Chrome()
driver.get(url)
time.sleep(3)
data = driver.page_source
driver.close()
# 创建响应对象
res = HtmlResponse(url=url, body=data, encoding='utf-8', request=reqeust)
return res
- 2.在settings.py文件中DOWNLOADER_MIDDLEWARES 把新的类名更改上
- 3.重新运行