“ 一切不经过项目验证的代码都是耍流氓,今天我们就通过一个简单的招聘网站的数据归档进行当前热门岗位的大数据分析,最后以wordcloud进行显示。本文为数据爬取篇。”
项目准备:
这次我们来比较完整的抓取拉勾网上面“Python”相关招聘信息以及招聘要求详情。
能联网的电脑、搭建好Python3以上环境,如果环境没有配置,可以参考我原来的文章 Python的安装与配置。IDE这次我们采用Jupyter Notebook ,采集我们使用selenium+pyquery,为什么用这个?说起来都是泪,文末我再解释。数据分析使用pandas。
分析页面,寻找数据来源
打开拉勾网,搜索“Python”得到下面这个页面。最近疫情我被关在武汉了,我就以武汉站为目的地好了。共30页,每页展示15个职位[职位(368)]。
![af72323e4cec7a1df6403fc8965f11ac.png](https://i-blog.csdnimg.cn/blog_migrate/70dd5ea9994178dadc928c57c556f03a.jpeg)
![c0c450ec3d72b59e3c12b6e8fdaa774b.png](https://i-blog.csdnimg.cn/blog_migrate/361aba7db5116c272618e982ac230f09.jpeg)
通过selenium采集比request采集的效率要低许多,因为是模拟浏览器方式进行抓取,所以每次都要对页面进行渲染。但是同样也有个好处,就是不用在意header和cookie问题。废话不多说,直接开始操作
按照以前我们的方法,在Notebook中新建Python 3文件:
引入各种模块:
import pyquery as pqfrom selenium import webdriverimport pandas as pdimport timeimport os
初始化一个浏览器:
driver = webdriver.Firefox()driver.implicitly_wait(5)driver.get("https://www.lagou.com/")
在打开的页面中,进行处理拉勾网的登陆状态
while True: i = input("已登陆成功请输入“OK”:") if i == 'OK': break elif i == 'quit': print("取消执行,关闭!") os._exit(1)
登陆成功后,在命令行输入窗输入“OK”,会进入下一步执行。
进入列表采集:
print("开始执行采集")data = []driver.get("https://www.lagou.com/jobs/list_Python/p-city_184?&cl=false&fromSearch=true&labelWords=&suginput=")while True: but_class = driver.find_element_by_css_selector(".pager_next").get_attribute('class') if but_class == 'pager_next ': driver.find_element_by_xpath("//span[@action='next']").click() items = pq.PyQuery(driver.page_source).find(".con_list_item") data += getPosition(items) time.sleep(2) else: print('列表采集结束') break
我们单独定义了一个采集方法,getPosition 这个方法接收一个pyquery的对象。
方法代码如下:
def getPosition(items): datalist=[] for item in items.items(): temp = dict() temp['职位ID']= item.attr('data-positionid') temp['职位名']= item.attr('data-positionname') temp['薪资范围']= item.attr('data-salary') temp['公司ID']= item.attr('data-companyid') temp['公司名']= item.attr('data-company') temp['职位链接']=pq.PyQuery(item).find(".position_link").attr("href") temp['发布时间']=pq.PyQuery(item).find(".format-time").text() temp['猎头名称']=pq.PyQuery(item).find(".hr_name").text() temp['猎头ID']=pq.PyQuery(item).find(".target_hr").text() temp['工作经验']=pq.PyQuery(item).find(".p_bot>.li_b_l").remove(".money").text() temp['公司主页']=pq.PyQuery(item).find(".company_name>a").attr('href') temp['公司描述']=pq.PyQuery(item).find(".industry").text() temp['岗位亮点']=pq.PyQuery(item).find(".li_b_r").text() datalist.append(temp) return datalist
到这里,主要列表的采集和整理工作就结束了,我们把采集到的数据整合到pandas中,并保存到csv文件,以方便后面使用。
csv = pd.DataFrame(data)csv.to_csv("lagou.csv")
![e6a082eac2dc908aa1abb93b943495aa.png](https://i-blog.csdnimg.cn/blog_migrate/b127eb04d726486d5110c978d2f72b7c.jpeg)
截图为保存的DataFrame。可以看到,我们保存了二级页名,和公司相关的信息。
一共采集了368条数据。这个时候,我们开始进行第二步详情数据的完善采集。
我们先查看一个二级页面,看一下数据格式
在网页里面点击任意一个职位进入查看详情,例如https://www.lagou.com/jobs/4263258.html:
![6f70cfb3a222a814dd11116056c3e5f2.png](https://i-blog.csdnimg.cn/blog_migrate/8dd36bee41254732b458dcb62642424e.jpeg)
参照我们最开始的方法可以发现,我们需要的信息就在右键html网页源代码里面,就在一个class='job_bt'的dd标签里面:
![2050f5b6ffffd1eeac55d60413d379bc.png](https://i-blog.csdnimg.cn/blog_migrate/4462afe25e97e18636b1ea1815f9e2ce.jpeg)
我这里使用pyquery 来处理html内容:
text =pq.PyQuery(driver.page_source).find(".job-detail").text()with open("./data/%s.txt" %row[1],"w+") as f: f.write(text)
如果对JQuery熟悉的同学一定可以看出来,PyQuery的选择器实在是简单。。
最后别忘了测试一下存储的数据是否正确:
彩蛋:
最开始写这个文章时,我是打算使用request进行数据采集的,在代码实现的时候发现一个问题,拉勾网的防爬做得还是挺不错,在采集列表页面时,同一header的使用一旦超过5次就被判定为爬虫。在这个坑上足足花了二个小时。虽然这个坑大概是什么原因,但是我现在实在是太困,不想再花时间处理。(页面的COOKIE是经过页面Js调用生成的)如果以后有精力再说吧。
总结
- 先分析页面,知道数据从哪里来、什么格式?(网页源代码html?Network面板的xhr请求到的json数据?),本项目使用的selenium,所以只用处理页面数据。
- 根据数据来源格式确定使用解析方式
- 处理防爬机制
- 利用def定义不同的函数处理单独的请求可以让代码更清晰
- 把获取的内容存储到文件(简单横竖列表数据存.csv),注意要转为字符串存储,注意文件名要唯一。
- 尽可能在必要的位置合理的使用time.sleep(1)延缓一下,特别是防爬高的站点,一定要加上
- 代码要一点点测试,Jupyter Notebook是一个神器。
如果需要项目源码,请关注,并私信明哥:"lagou"
最后:如果你正在学习Python的路上,或者准备打算学习Python、明哥会陪着你陪你一起共同进步!
手打不易,有用的话,请记得关注转发。