scrapy初始第三波——CrawlSpider爬取拉勾招聘网
来源:互联网 发布:ps 淘宝女装 编辑:程序博客网 时间:2024/06/10 05:32
一,前言
之前利用scrapy爬取伯乐在线,知乎时是用到scrapy的basic模板,即Spider,这次用CrawlSpider来爬取拉勾网的招聘信息
CrawlSpider基于Spider,但是可以说是为全站爬取而生,是目前最流行的scrapy模板
二,创建工程
在cmd中cd进入项目的目录,然后输入:scrapy gensipder -t crawl lagou www.lagou.com
默认生成:
三,简要说明
CrawlSpider是爬取那些具有一定规则网站的常用的爬虫,它基于Spider并有一些独特属性,也就是之前spider的爬取规则现在也适用,下面的参数可以按ctrl点击CrawlSpider获取源码
- rules: 是Rule对象的集合,用于匹配目标网站并排除干扰
- parse_start_url: 用于爬取起始响应,必须要返回Item,Request中的一个。
因为rules是Rule对象的集合,所以这里也要介绍一下Rule对象
它有几个参数:linkExtractor、callback=None、cb_kwargs=None、follow=None、process_links=None、process_request=None
- callback为回调函数,传入一个str,即回调函数的名字
- follow为boolean类型,为true就继续跟踪,为false则不往下跟踪
其中的linkExtractor既可以自己定义,也可以使用已有LinkExtractor类,主要参数为:
- allow:满足括号中“正则表达式”的值会被提取,如果为空,则全部匹配。
- deny:与这个正则表达式(或正则表达式列表)不匹配的URL一定不提取。
- allow_domains:会被提取的链接的domains。
- deny_domains:一定不会被提取链接的domains。
- restrict_xpaths:使用xpath表达式,和allow共同作用过滤链接。还有一个类似的restrict_cs
4.1 rule的编写
输入拉勾网首页:https://www.lagou.com/
观察职位的url:https://www.lagou.com/jobs/3157876.html 为https://www.lagou.com/jobs/\d+.html 格式
此外我们在进入职位url之前必须从 https://www.lagou.com/zhaopin/Android/ ,https://www.lagou.com/gongsi/j118082.html之类的url进入,所以匹配https://www.lagou.com/zhaopin/* https://www.lagou.com/gongsi/j\d+
4.2 parse_item的编写
这里不详细分析了,在如图一个个用css,或者xpath分析
具体代码如下:
# -*- coding: utf-8 -*-import scrapyfrom scrapy.linkextractors import LinkExtractorfrom scrapy.spiders import CrawlSpider, Rulefrom ArticleSpider.items import FirstItemLoader, LagouJobItemclass LagouSpider(CrawlSpider): name = 'lagou' allowed_domains = ['www.lagou.com'] start_urls = ['https://www.lagou.com/zhaopin/Python/'] rules = ( Rule(LinkExtractor(allow=("zhaopin/.*",)),follow=True), Rule(LinkExtractor(allow=("gongsi/j\d+.html",)), follow=True), Rule(LinkExtractor(allow=r'jobs/\d+.html'), callback='parse_job', follow=True), ) def parse_job(self, response): #解析拉勾网的职位 # pass # #i['domain_id'] = response.xpath('//input[@id="sid"]/@value').extract() # #i['name'] = response.xpath('//div[@id="name"]').extract() # #i['description'] = response.xpath('//div[@id="description"]').extract() item_loader = FirstItemLoader(item=LagouJobItem(),response=response) item_loader.add_css("title", ".job-name::attr(title)") item_loader.add_value("url", response.url) item_loader.add_css("salary", ".job_request .salary::text") item_loader.add_xpath("job_city", "//*[@class='job_request']/p/span[2]/text()") item_loader.add_xpath("work_years", "//*[@class='job_request']/p/span[3]/text()") item_loader.add_xpath("degree_need", "//*[@class='job_request']/p/span[4]/text()") item_loader.add_xpath("job_type", "//*[@class='job_request']/p/span[5]/text()") item_loader.add_css("tags", '.position-label li::text') item_loader.add_css("publish_time", ".publish_time::text") item_loader.add_css("job_advantage", ".job-advantage p::text") item_loader.add_css("job_desc", ".job_bt div") item_loader.add_css("job_addr", ".work_addr") item_loader.add_css("company_name", "#job_company dt a img::attr(alt)") item_loader.add_css("company_url", "#job_company dt a::attr(href)") # item_loader.add_value("crawl_time", datetime.now()) job_item = item_loader.load_item() # print(job_item) yield job_item pass
其中items代码如下:
import reimport scrapyfrom scrapy.loader.processors import TakeFirst,MapCompose,Joinfrom scrapy.loader import ItemLoade
class FirstItemLoader(ItemLoader): #自定义itemloader,继承scrapy的ItemLoader类 default_output_processor = TakeFirst()
def remove_splash(value): #去掉工作城市的斜线 return value.replace("/","")class LagouJobItem(scrapy.Item): #拉勾网职位信息 title = scrapy.Field() url = scrapy.Field() url_object_id = scrapy.Field() salary = scrapy.Field() job_city = scrapy.Field( input_processor=MapCompose(remove_splash), ) work_years = scrapy.Field( input_processor = MapCompose(remove_splash), ) degree_need = scrapy.Field( input_processor = MapCompose(remove_splash), ) job_type = scrapy.Field() publish_time = scrapy.Field() job_advantage = scrapy.Field() job_desc = scrapy.Field() job_addr = scrapy.Field( ) company_name = scrapy.Field() company_url = scrapy.Field() tags = scrapy.Field( input_processor = Join(",") ) crawl_time = scrapy.Field()
运行结果:
如果没有爬取成功提示要登录,可以看看下面的应对措施
五,应对反爬措施
由于拉勾的反爬措施比较严格,所以可以会需要登录才可以访问,这里采取了反反爬虫的方法有:
5.1,设置随机的user-agent
首先导入 fake_useragent :pip install fake_usergent
然后在中间件 middlewares.py 添加以下代码:
from fake_useragent import UserAgent
#随机更换user-agentclass RandomUserAgentMiddlware(object): def __init__(self,crawler): super(RandomUserAgentMiddlware, self).__init__() self.ua = UserAgent() @classmethod def from_crawler(cls,crawler): return cls(crawler) def process_request(self,request,spider): request.headers.setdefault('User-Agent',self.ua.random)
这样每次下载页面时就会传入不同的 user-agent
别忘了在setting添加middlewares设置,否则该设置不生效
DOWNLOADER_MIDDLEWARES = { 'ArticleSpider.middlewares.RandomUserAgentMiddlware': 543, 'scrapy.downloadermiddlewares.useragent.UserAgentMiddleware': None, }
5.2,设置下载延迟
在setting中添加设置:
DOWNLOAD_DELAY = 10
这样基本就能爬取拉勾网大部分招聘信息了,如果还是不行,还能采取selenium驱动谷歌浏览器来访问,还可以设置自动登录,或者自动修改ip来解决,这里就不一一列举
六,问题
CrawlSpider如何工作的?
因为CrawlSpider继承了Spider,所以具有Spider的所有函数。首先由
start_requests
对start_urls
中的每一个url发起请求(make_requests_from_url
),这个请求会被parse接收。在Spider里面的parse需要我们定义,但CrawlSpider定义parse
去解析响应(self._parse_response(response, self.parse_start_url, cb_kwargs={}, follow=True)
)_parse_response根据有无callback
,follow
和self.follow_links
执行不同的操作def _parse_response(self, response, callback, cb_kwargs, follow=True): ##如果传入了callback,使用这个callback解析页面并获取解析得到的reques或item if callback: cb_res = callback(response, **cb_kwargs) or () cb_res = self.process_results(response, cb_res) for requests_or_item in iterate_spider_output(cb_res): yield requests_or_item ## 其次判断有无follow,用_requests_to_follow解析响应是否有符合要求的link。 if follow and self._follow_links: for request_or_item in self._requests_to_follow(response): yield request_or_item
其中
_requests_to_follow
又会获取link_extractor
(这个是我们传入的LinkExtractor)解析页面得到的link(link_extractor.extract_links(response))
,对url进行加工(process_links,需要自定义),对符合的link发起Request。使用.process_request
(需要自定义)处理响应。
- scrapy初始第三波——CrawlSpider爬取拉勾招聘网
- python scrapy爬虫 CrawlSpider 拉钩招聘网302重定向问题解决方案 , 修改setting信息,添加cookie请求
- Scrapy研究探索(六)——自动爬取网页之II(CrawlSpider)
- Scrapy研究探索(六)——自动爬取网页之II(CrawlSpider)
- Scrapy研究探索(六)——自动爬取网页之II(CrawlSpider)
- Scrapy研究探索(六)——自动爬取网页之II(CrawlSpider)
- Scrapy-CrawlSpider爬虫组件
- Scrapy-CrawlSpider爬虫组件
- Scrapy-CrawlSpider爬虫组件
- 六.scrapy crawlspider
- Scrapy第一战—爬取智联招聘
- scrapy初始第一波——爬取伯乐在线所有文章
- scrapy初始第二波——爬取知乎首页的问题和回答并写入mysql中
- scrapy爬虫:CrawlSpider用法与总结
- scrapy学习(三) crawlspider源码解析
- Scrapy框架利用CrawlSpider创建自动爬虫
- Scrapy框架利用CrawlSpider创建自动爬虫
- scrapy 爬取腾讯招聘网
- tensorflow常用函数及概念
- DevExpress的框架介绍,给初学者的一些建议
- java语言基础(92)——使用Lock锁实现线程安全
- struts2的异常处理
- RPG难题
- scrapy初始第三波——CrawlSpider爬取拉勾招聘网
- [转]手把手教你使用Git
- C语言 通过指针,数组名 遍历一位数组
- hhh
- PYTHON机器学习实战——PCA主成分分析 数据降维
- PAT 甲级 1032. Sharing (25)
- 第三章习题5第3小题
- 计数排序
- BZOJ[1671][Usaco2005 Dec]Knights of Ni 骑士 Floodfill