爬虫实战(二) 51job移动端数据采集

    在上一篇51job职位信息的爬取中,对岗位信息div下各式各样杂乱的标签,简单的Xpath效果不佳,加上string()函数后,也不尽如人意。因此这次我们跳过桌面web端,选择移动端进行爬取。

一、代码结构

按照下图所示的爬虫基本框架结构,我将此份代码分为四个模块——URL管理、HTML下载、HTML解析以及数据存储。

二、URL管理模块

这个模块负责搜索框关键词与对应页面URL的生成,以及搜索结果不同页数的管理。首先观察某字段(大数据, UTF-8为‘E5A4A7 E695B0 E68DAE‘) 全国范围内的结果,前三页结果的URL如下:

URL前半部分:

这部分中我们可以看到两处处不同,第一处为编码后‘2,?.html‘中间的数字,这是页数。另一处为参数stype的值,除第一页为空之外,其余都为1。另外,URL中有一连串的数字,这些是搜索条件,如地区、行业等,在这儿我没有用上。后面的一连串字符则为搜索关键词的字符编码。值得注意的是,有些符号在URL中是不能直接传输的,如果需要传输的话,就需要对它们进行编码。编码的格式为‘%‘加上该字符的ASCII码。因此在该URL中,%25即为符号‘%‘。

URL后半部分:

后半部分很明显的就能出首页与后面页面的URL参数相差很大,非首页的URL后半部分相同。

因此我们需要对某关键字的搜索结果页面分两次处理,第一次处理首页,第二次可使用循环处理后续的页面。

  1. if __name__ == ‘__main__‘:  
  2.     key = ‘数据开发‘  
  3.     # 第一页  
  4.     url = ‘https://search.51job.com/list/000000,000000,0000,00,9,99,‘+key+‘,2,1.html?lang=c&stype=&postchannel=0000&workyear=99&cotype=99°reefrom=99&jobterm=99&companysize=99&providesalary=99&lonlat=0%2C0&radius=-1&ord_field=0&confirmdate=9&fromType=&dibiaoid=0&address=&line=&specialarea=00&from=&welfare=‘  
  5.     getUrl(url)  
  6.     # 后页[2,100)  
  7.     urls = [‘https://search.51job.com/list/000000,000000,0000,00,9,99,‘+key+‘,2,{}.html?lang=c&stype=1&postchannel=0000&workyear=99&cotype=99°reefrom=99&jobterm=99&companysize=99&lonlat=0%2C0&radius=-1&ord_field=0&confirmdate=9&fromType=&dibiaoid=0&address=&line=&specialarea=00&from=&welfare=‘.format(i) for i in range(2,30)]  
  8.     for url in urls:  
  9.         getUrl(url)  

三、HTML下载模块

下载HTMl页面分为两个部分,其一为下载搜索结果某一页的HTML页面,另一部分为下载某一岗位具体页面。由于页面中具体岗位URL需要从搜索结果页面中获取,所以将下载搜索结果页面及获取具体岗位URL放入一个函数中,在提取到具体岗位URL后,将其传入至另一函数中。

3.1搜索结果页面下载与解析

下载页面使用的是requests库的get()方法,得到页面文本后,通过lxml库的etree将其解析为树状结构,再通过Xpath提取我们想要的信息。在搜索结果页面中,我们需要的是具体岗位的URL,打开开发者选项,找到岗位名称。

我们需要的是<a>标签里的href属性。右键,复制——Xpath,得到该属性的路径。

  1. //*[@id="resultList"]/div/p/span/a/@href  

由于xpath返回值为一个列表,所以通过一个循环,将列表内URL依次传入下一函数。

  1. def getUrl(url):  
  2.     print(‘New page‘)  
  3.     res = requests.get(url)  
  4.     res.encoding = ‘GBK‘  
  5.     if res.status_code == requests.codes.ok:  
  6.         selector = etree.HTML(res.text)  
  7.         urls = selector.xpath(‘//*[@id="resultList"]/div/p/span/a/@href‘)  
  8.         #                      //*[@id="resultList"]/div/p/span/a  
  9.         for url in urls:  
  10.             parseInfo(url)  
  11.             time.sleep(random.randrange(1, 4))  

3.2具体岗位信息页面下载

该函数接收一个具体岗位信息的参数。由于我们需要对移动端网页进行处理,所以在发送请求时需要进行一定的伪装。通过设置headers,使用手机浏览器的用户代理,再调用get()方法。

  1. def parseInfo(url):  
  2.     headers = {  
  3.         ‘User-Agent‘: ‘Opera/9.80 (Android 2.3.4; Linux; Opera Mobi/ADR-1301071546) Presto/2.11.355 Version/12.10‘  
  4.     }  
  5.     res = requests.get(url, headers=headers)  

四、HTML解析模块

在3.2中,我们已经得到了岗位信息的移动端网页源码,因此再将其转为etree树结构,调用Xpath即可得到我们想要的信息。

需要注意的是页面里岗位职责div里,所有相关信息都在一个<article>标签下,而不同页面的<article>下层标签并不相同,所以需要将该标签下所有文字都取出,此处用上了string()函数。

  1. selector = etree.HTML(res.text)  
  2.     
  3. title = selector.xpath(‘//*[@id="pageContent"]/div[1]/div[1]/p/text()‘)  
  4. salary = selector.xpath(‘//*[@id="pageContent"]/div[1]/p/text()‘)  
  5. company = selector.xpath(‘//*[@id="pageContent"]/div[2]/a[1]/p/text()‘)  
  6. companyinfo = selector.xpath(‘//*[@id="pageContent"]/div[2]/a[1]/div/text()‘)  
  7. companyplace = selector.xpath(‘//*[@id="pageContent"]/div[2]/a[2]/span/text()‘)  
  8. place = selector.xpath(‘//*[@id="pageContent"]/div[1]/div[1]/em/text()‘)  
  9. exp = selector.xpath(‘//*[@id="pageContent"]/div[1]/div[2]/span[2]/text()‘)  
  10. edu = selector.xpath(‘//*[@id="pageContent"]/div[1]/div[2]/span[3]/text()‘)  
  11. num = selector.xpath(‘//*[@id="pageContent"]/div[1]/div[2]/span[1]/text()‘)  
  12. time = selector.xpath(‘//*[@id="pageContent"]/div[1]/div[1]/span/text()‘)  
  13. info = selector.xpath(‘string(//*[@id="pageContent"]/div[3]/div[2]/article)‘)  
  14. info = str(info).strip()  

五、数据存储模块

首先创建.csv文件,将不同列名称写入首行。

  1. fp = open(‘51job.csv‘,‘wt‘,newline=‘‘,encoding=‘GBK‘,errors=‘ignore‘)  
  2. writer = csv.writer(fp)  
  3. writer.writerow((‘职位‘,‘薪资‘,‘公司‘,‘公司信息‘,‘公司地址‘,‘地区‘,‘工作经验‘,‘学历‘,‘人数‘,‘时间‘,‘岗位信息‘))  

再在解析某一页面数据后,将数据按行写入.csv文件。

  1. writer.writerow((title,salary,company,companyinfo,companyplace,place,exp,edu,num,time,info))  

源码:爬取51job移动端源码(12月)

相关:智联招聘源码分析

贪吃蛇链表实现及部分模块优化

原文地址:https://www.cnblogs.com/magicxyx/p/10128914.html

时间: 2024-10-13 11:41:07

爬虫实战(二) 51job移动端数据采集的相关文章

Python爬虫实战二之爬取百度贴吧帖子

大家好,上次我们实验了爬取了糗事百科的段子,那么这次我们来尝试一下爬取百度贴吧的帖子.与上一篇不同的是,这次我们需要用到文件的相关操作. 前言 亲爱的们,教程比较旧了,百度贴吧页面可能改版,可能代码不好使,八成是正则表达式那儿匹配不到了,请更改一下正则,当然最主要的还是帮助大家理解思路. 2016/12/2 本篇目标 1.对百度贴吧的任意帖子进行抓取 2.指定是否只抓取楼主发帖内容 3.将抓取到的内容分析并保存到文件 1.URL格式的确定 首先,我们先观察一下百度贴吧的任意一个帖子. 比如:ht

转 Python爬虫实战二之爬取百度贴吧帖子

静觅 » Python爬虫实战二之爬取百度贴吧帖子 大家好,上次我们实验了爬取了糗事百科的段子,那么这次我们来尝试一下爬取百度贴吧的帖子.与上一篇不同的是,这次我们需要用到文件的相关操作. 本篇目标 1.对百度贴吧的任意帖子进行抓取 2.指定是否只抓取楼主发帖内容 3.将抓取到的内容分析并保存到文件

2017.08.04 Python网络爬虫之Scrapy爬虫实战二 天气预报

1.项目准备:网站地址:http://quanzhou.tianqi.com/ 2.创建编辑Scrapy爬虫: scrapy startproject weather scrapy genspider HQUSpider quanzhou.tianqi.com 项目文件结构如图: 3.修改Items.py: 4.修改Spider文件HQUSpider.py: (1)先使用命令:scrapy shell http://quanzhou.tianqi.com/   测试和获取选择器: (2)试验选择

2017.08.04 Python网络爬虫之Scrapy爬虫实战二 天气预报的数据存储问题

1.数据存储到JSon:程序阅读一般都是使用更方便的Json或者cvs等待格式,继续讲解Scrapy爬虫的保存方式,也就是继续对pipelines.py文件动手脚 (1)创建pipelines2json.py文件: import timeimport jsonimport codecs class WeatherPipeline(object): def process_item(self, item, spider): today=time.strftime('%Y%m%d',time.loc

Python网络爬虫实战(二)数据解析

上一篇说完了如何爬取一个网页,以及爬取中可能遇到的几个问题.那么接下来我们就需要对已经爬取下来的网页进行解析,从中提取出我们想要的数据. 根据爬取下来的数据,我们需要写不同的解析方式,最常见的一般都是HTML数据,也就是网页的源码,还有一些可能是Json数据,Json数据是一种轻量级的数据交换格式,相对来说容易解析,它的格式如下. { "name": "中国", "province": [{ "name": "黑龙江

纯golang爬虫实战(二)

接上一篇文章https://www.cnblogs.com/pu369/p/12202845.html只讲了原理,抽时间写个了实用版,将员工信息爬取到一个TXT文档中,以便于查询,上代码: //纯golang爬虫 package main import ( "bytes" "fmt" "io/ioutil" "net/http" "net/http/cookiejar" "regexp"

基于C#.NET的高端智能化网络爬虫(二)(攻破携程网)

本篇故事的起因是携程旅游网的一位技术经理,豪言壮举的扬言要通过他的超高智商,完美碾压爬虫开发人员,作为一个业余的爬虫开发爱好者,这样的言论我当然不能置之不理.因此就诞生了上一篇基础爬虫以及这一篇高级爬虫的开发教程. 有人评论我上一篇的简单爬虫:代码太过简单以至于弱爆了,真是被这群有文化的孩子给雷到了!不得不猜测你是不是携程网的托儿,我还没写完你咋就知道弱爆了?看来不下点猛料你是得不到满足啊! 今天我们就来学习高级爬虫的开发,同时我们还要利用之前的简单爬虫程序,来实现分布式爬虫的Links Mas

Java爬虫实战(二):抓取一个视频网站上2015年所有电影的下载链接

前言:这是Java爬虫实战的第二篇文章,在第一篇文章仅仅只是抓取目标网站的链接的基础上,进一步提高难度,抓取目标页面上我们所需要的内容并保存在数据库中.这里的测试案例选用了一个我常用的电影下载网站(http://www.80s.la/).本来是想抓取网站上的所有电影的下载链接,后来感觉需要的时间太长,因此改成了抓取2015年电影的下载链接. 注:文末有我抓取到的整个列表的下载链接(包括:电影名称和迅雷下载链接) 一 原理简介 其实原理都跟第一篇文章差不多,不同的是鉴于这个网站的分类列表实在太多,

Python爬虫实战(4):豆瓣小组话题数据采集—动态网页

1, 引言 注释:上一篇<Python爬虫实战(3):安居客房产经纪人信息采集>,访问的网页是静态网页,有朋友模仿那个实战来采集动态加载豆瓣小组的网页,结果不成功.本篇是针对动态网页的数据采集编程实战. Python开源网络爬虫项目启动之初,我们就把网络爬虫分成两类:即时爬虫和收割式网络爬虫.为了适应各种应用场景,GooSeeker的整个网络爬虫产品线包含了四类产品,如下图所示: 本实战是上图中的"独立python爬虫"的一个实例,以采集豆瓣小组讨论话题(https://w