900字范文,内容丰富有趣,生活中的好帮手!
900字范文 > 实战案例 | Scrapy 集成Selenium爬取智联招聘数据

实战案例 | Scrapy 集成Selenium爬取智联招聘数据

时间:2023-09-20 01:00:53

相关推荐

实战案例 | Scrapy 集成Selenium爬取智联招聘数据

人生苦短,快学Python!

初学scrapy之后,发现就是效率对比于selenium和requests快了很多,那么问题来了,如果网站设置了反爬,比如User-Agent反爬,cookie反爬,IP封禁等等,所以我们需要通过集成selenium到scrapy中,绕过网站反爬,达到目的。

这里选择智联招聘网站作为案例,就是虽然不是动态网页,但是它需要模拟登录,所以我们通过scrapy集成selenium进行数据抓取。

一、需求分析

打开目标网站,搜索web前端开发工程师

这是首页,由于我的当前位置在武汉,所以系统自动定位到武汉,点击搜索后:

这个就是需要通过selenium出路的一个点。

手动登录后得到以下界面:

我们的目标是每一条招聘信息的8条数据:

name职位名称

salary薪资

adress地区

experience经验

eduBack教育背景

company公司名称

companyType公司类型

scale公司规模

info简介

二、scrapy项目文件配置

定义items

importscrapyclassZlzpItem(scrapy.Item):name=scrapy.Field()***薪资公司规模...***info=scrapy.Field()

定义scrapy爬虫:zl.py(智联)

#这里先说明下url:firstPageUrl:'/?jl=736&kw=web%E5%89%8D%E7%AB%AF%E5%B7%A5%E7%A8%8B%E5%B8%88&p=1'#作为第一页的url,下面的myspider.py中就不在展示,避免代码冗余。base_url='/?jl=736&kw=web%E5%89%8D%E7%AB%AF%E5%B7%A5%E7%A8%8B%E5%B8%88&p={}'

然后下面是zl.py的源码:(分为几个部分)

1、初始化设置:

#-*-coding:utf-8-*-importscrapyfromzlzp.itemsimportZlzpItemcount=1#定义一个全局变量,与base_url构建下一页的urlclassZlSpider(scrapy.Spider):name='zl'allowed_domains=['']start_urls=[firstPageUrl]

2、parse函数:

defparse(self,response):globalcountcount+=1#每解析一次页面,让count+1,和baseurl构造下一页的urljobList=response.xpath('//div[@class="positionlist"]/div/a')forjobinjobList:name=job.xpath("./div[1]/div[1]/span[1]/text()").extract_first()...salary***,company***,....info=job.xpath("./div[3]/div[1]//text()").extract_first()item=ZlzpItem(name=name,salary=salary,company=company,adress=adress,experience=experience,eduBack=eduBack,companyType=companyType,scale=scale,info=info)yielditem

3、分页:

next_url='/?jl=736&kw=web%E5%89%8D%E7%AB%AF%E5%B7%A5%E7%A8%8B%E5%B8%88&p={}'.format(count)ifcount==34:returnNone#设置程序停止的条件ifnext_url:yieldscrapy.Request(next_url,callback=self.parse)

定义下载器中间件(DownloadMiddleware):myDownloadMiddleware.py

fromselenium.webdriver.support.uiimportWebDriverWaitfromselenium.webdriver.supportimportexpected_conditionsasEC...classZlzpDownloaderMiddleware:def__init__(self):self.driver=webdriver.Chrome()defprocess_request(self,request,spider):self.driver.get(request.url)time.sleep(3)#休息3s#设置显示等待,由于需要登录,我们手机扫码登录,知道页面出现(即url显示为firstpageurl)WebDriverWait(self.driver,1000).until(EC.url_contains(request.url))time.sleep(6)#登录成功之后页面需要时间加载出来,再休息几秒returnHtmlResponse(url=self.driver.current_url,body=self.driver.page_source,encoding="utf-8",request=request)#然后把这个response对象返回给爬虫(zl.py)

说明:

selenium集成到scrapy中的核心就是在爬虫中间件中拦截请求,把处理后的响应对象返回,对应于爬虫文件(这里的zl.py)parse函数中的response,如果不集成selenium,那么response对象不能很好应对网站的反爬.

此处的parse_request方法中只有少量的selenium代码,因为动态操作其实不多.

重点:return后面的response对象:

在这里我们不能return None,如果return None,那么请求会被发送到下载中间件去下载这个页面,在将这个页面的response返回给spider(hr.py)。但是我们上面browser.get的时候就已经下载了这个页面的内容,所以没有必要在下载一次,我们只要制定一个response对象,直接返回这个response给spider即可

定义管道(Pipeline):pipelines.py

fromitemadapterimportItemAdapterimportcsvclassZlzpPipeline:def__init__(self):self.f=open('zlJob.csv','w',encoding='utf-8',newline='')#self.file_name=['name','upTime','salary','needs','welfare','company','scale','types']self.file_name=['name','salary','company','adress','experience','eduBack','companyType','scale','info']self.writer=csv.DictWriter(self.f,fieldnames=self.file_name)self.writer.writeheader()defprocess_item(self,item,spider):self.writer.writerow(dict(item))#写入spider传过来的具体数值returnitem#写入完返回defclose_spider(self,spider):self.f.close()

settings.py配置

BOT_NAME='zlzp'SPIDER_MODULES=['zlzp.spiders']NEWSPIDER_MODULE='zlzp.spiders'LOG_LEVEL='WARNING'......ROBOTSTXT_OBEY=False......DEFAULT_REQUEST_HEADERS={'user-agent':'Mozilla/5.0(WindowsNT10.0;Win64;x64)AppleWebKit/537.36(KHTML,likeGecko)Chrome/91.0.4472.106Safari/537.36','Accept':'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8','Accept-Language':'en',}......DOWNLOADER_MIDDLEWARES={'zlzp.middlewares.ZlzpDownloaderMiddleware':543,}......ITEM_PIPELINES={'zlzp.pipelines.ZlzpPipeline':300,}......

......表示注释代码,这里省略。

三、程序运行

命令行键入:

scrapycrawlhr

pic1:运行程序结束到第34页,对应count = 34

pic02:(csv文件)

四、数据简单分析

查看数据

importpandasaspddf=pd.read_csv('./zlJob.csv')df.head()

薪资饼图展示

c=(Pie(init_opts=opts.InitOpts(bg_color="white")).add("",[list(z)forzinzip(typesX,number)])#zip函数两个部分组合在一起list(zip(x,y))----->[(x,y)].set_global_opts(title_opts=opts.TitleOpts(title="类型:"))#标题.set_series_opts(label_opts=opts.LabelOpts(formatter="{b}:{c}"))#数据标签设置)c.render_notebook()

经验要求柱图展示

frompyecharts.chartsimportBarbar=Bar()bar.add_xaxis(['3-5年','1-3年','不限','5-','无经验','1年以下','以上'])bar.add_yaxis('经验要求',[462,329,83,78,19,15,4])bar.render()

学历要求柱图展示

c=(Pie(init_opts=opts.InitOpts(bg_color="white")).add("",[list(z)forzinzip(educationTypes,number)])#zip函数两个部分组合在一起list(zip(x,y))----->[(x,y)].set_global_opts(title_opts=opts.TitleOpts(title="类型:"))#标题.set_series_opts(label_opts=opts.LabelOpts(formatter="{b}:{c}"))#数据标签设置)c.render_notebook()

大多数要求本科学历,或者说大专及以上学历。

公司类型柱图展示

c=(Pie(init_opts=opts.InitOpts(bg_color="white")).add("",[list(z)forzinzip(companyTypes,number)])#zip函数两个部分组合在一起list(zip(x,y))----->[(x,y)].set_global_opts(title_opts=opts.TitleOpts(title="类型:"))#标题.set_series_opts(label_opts=opts.LabelOpts(formatter="{b}:{c}"))#数据标签设置)c.render_notebook()

可以看到大多数公司是民营或者上市公司。

五、总结

页面翻页处理,由于我们只是使用selenium就是打开网页请求数据,所以一般在爬虫文件中进行翻页处理,如果对应的下一页的a标签的href属性不是下一页的页面url,我们需要设置动态全局变量,构建动态的url。

下载中间件中设置的selenium的相关操作,动态点击,页面滚轮操作,显隐式等待等等,重要的是返回的response对象,这个是集成selenimu到scrapy的核心,在下载中间件中拦截请求,把处理后的response对象返回给爬虫。

分享给更多朋友,转发,点赞,在看

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。