selenium+lxml爬取(查询)拉勾网职位信息

拉勾网: 是一家专为拥有3至10年工作经验的资深互联网从业者,提供工作机会的招聘网站。拉勾网专注于在为求职者提供更人性化、专业化服务的同时,降低企业端寻觅良才的时间和成本。拉勾网致力于帮助互联网人士做出更好的职业选择,让求职者每一次职业选择变的更加明智。
官网: https://www.lagou.com/

技术难度: 爬取拉勾网的技术难点主要是在它的反反爬虫机制,很容易就会触发它。我曾经看网上的视频教程,拉勾网的反爬虫做了很多的更新,所有直接就连网页的源码也获取不了就被反爬虫了。后来尝试了headers,cookie,代理IP,但是都失败了。每次拉勾网的网页加载后,它的cookie值都是变化的,并且只能使用一次。

数据加载方式: 拉勾网的数据加载方式和很多的网站一样,使用json文件加载,随便搜索一个职位看看
selenium+lxml爬取(查询)拉勾网职位信息_第1张图片
从图中可以看出就是通过它加载这些数据信息的,复制它的路径在该浏览器打开试试
selenium+lxml爬取(查询)拉勾网职位信息_第2张图片
“操作频繁”,这不可能,我只是把它复制到浏览器打开而已,等了一段时间后,它还是这样。其实这就是遇到它的反爬虫了,就在当前浏览器打开也不行,因为它的cookie值就只能用一次。

解决方法: 使用selenium库,它可以模拟人做自动化测试,对付这个反爬虫虽说有点杀鸡用牛刀的嫌疑,但是效果的确非常棒。它可以获取网页源码,却不能解析网页源码,所以还导入lxml来提取HTML的信息。

实现思路

1、获取拉勾网URL

selenium可以从拉勾网的官网一步一步的自动进行,为了简便,就直接从选好工作后的链接进行了。在官网搜索职位,选择一个城市,就得到了URL。
selenium+lxml爬取(查询)拉勾网职位信息_第3张图片
现在就可以直接构造一个链接,把它的职位和城市传进去,为了模拟搜索,我就只是传了城市进去。

city = input("请输入您要查询的城市:")
url = 'https://www.lagou.com/jobs/list_python?px=default&city='+str(city)+'#filterBox'

模拟浏览器清空搜索框的职位后,重新输入职位信息

major = input("请输入您要查询的工作:")
driver = webdriver.Chrome()#控制浏览器,自动化
url = 'https://www.lagou.com/jobs/list_python?px=default&city='+str(city)+'#filterBox'
driver.get(url)#打开网页
inputJob = driver.find_element_by_xpath('//*[@id="keyword"]')#找到输入框
inputJob.clear()#清空输入框
inputJob.send_keys(major)#获得并输入刚才输入的工作
inputJob.send_keys(Keys.ENTER)#按回车键
2、自动获取网页中职位信息的页数

selenium+lxml爬取(查询)拉勾网职位信息_第4张图片
2.1、获取最大页数
从中可以看出最大的页数值就在倒数的第二个标签中,从倒数第二个span就可以获得它,并把它的类型转化成int型,作为循环的次数。

last_page = driver.find_element_by_xpath("//div[@class='pager_container']/span[last()-1]")
last_page = int(last_page.get_attribute("page"))#取到页数的数字
for i in range(1,last_page+1,1):#判断页面并限制循环次数,每个页面爬取一次
    print ("正在爬取第%s页......\n"% i)

2.2、点击下一页
拉勾网加载下一页后,该页面的URL并不会发生变化,所以就不能从URL入手了,只能通过点击下一页来完成获取下一个页面的信息。但是第一个页面的信息要完全获取完后才能点击下一页,在点击前必须要进行判断。

    while i>1:#第一次不执行,停止由最大页数循环控制
        next_page = driver.find_element_by_xpath("//div[@class='pager_container']/span[last()]")#获取下一页按钮
        next_page.click()#点击下一页
        break #跳出while循环,每次只做一次循环
3、获取网页源码

在获取网页或加载数据的地方,最好停5秒钟以上,防止被识破是爬虫程序

    time.sleep(5) #暂停五秒,注意反爬虫
    source = driver.page_source#获取该网页源码
4、解析并提取信息
html = etree.HTML(source)#解析网页
works = html.xpath('//*[@id="s_position_list"]/ul/li')#获取每条数据在的节点
for work in works:        
    position_name = work.xpath("./div[1]/div[1]/div[1]/a/h3/text()")[0] # 职位名称        
    position_url = work.xpath("./div[1]/div[1]/div[1]/a/@href")[0] #详情链接
    # 岗位描述,数组型数据
    desc = work.xpath('./div[2]/div[1]/span/text()')
    desc = str(desc).replace("[","").replace("', '",",").replace("]","").replace("'","")#把数据型转化成字符型才能使用replace替换字符        

    salary = work.xpath("./div[1]/div[1]/div[2]/div/span/text()")[0] #薪资  
    company_name = work.xpath("./div[1]/div[2]/div[1]/a/text()")[0] # 公司名称
    # 岗位需求
    job_request_spans = work.xpath("./div[1]/div[1]/div[2]/div/text()")[-1]
    job_request_spans = str(job_request_spans).replace("\n","").replace(" ","")
    job_experience = job_request_spans.split('/')[0] #截取出工作经验
    education = job_request_spans.split('/')[-1] #截取出学历
    #公司描述
    company_resquest = work.xpath("./div[1]/div[2]/div[2]/text()")[-1]
    company_resquests = str(company_resquest).replace("\n","").replace(" ","")
    company_work = company_resquests.split('/')[0] #截取出公司的工作
    company_resquest = company_resquests.split('/')[1] #截取出公司要求
    company_people = company_resquests.split('/')[-1] #截取出公司人数
    #公司福利
    company_welfare = work.xpath("./div[2]/div[2]/text()")
    if company_welfare != 0:#判断公司是否表明有福利,有则执行条件
        company_welfare = company_welfare[0]
    place = work.xpath("./div[1]/div[1]/div[1]/a/span/em/text()")[0]#获取所在城市位置

    position = (position_name,position_url,desc,salary,company_name,job_experience,education,company_work,company_resquest,company_people,company_welfare,place)
#         print (position,'\n')

    writer.writerow((position))#写入数据
5、源码汇总
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
import time,csv
from lxml import etree

#创建CSV文件
fp = open('G:\Lagouwang_GuiyangPython_job.csv','a',newline='',encoding='utf-8')
writer = csv.writer(fp)
writer.writerow(('职位名称','详情链接','工作描述','薪资','公司名称','工作经验','学历','公司业务','公司要求','公司人数','公司福利','公司地点')) #csv头部

city = input("请输入您要查询的城市:")
major = input("请输入您要查询的工作:")
driver = webdriver.Chrome()#控制浏览器,自动化
url = 'https://www.lagou.com/jobs/list_python?px=default&city='+str(city)+'#filterBox'
driver.get(url)#打开网页
inputJob = driver.find_element_by_xpath('//*[@id="keyword"]')#找到输入框
inputJob.clear()#清空输入框
inputJob.send_keys(major)#获得并输入刚才输入的工作
inputJob.send_keys(Keys.ENTER)#按回车键
time.sleep(6)#暂停的时间至少在5秒上,少了怕被反爬虫机制识别
last_page = driver.find_element_by_xpath("//div[@class='pager_container']/span[last()-1]")
last_page = int(last_page.get_attribute("page"))#取到页数的数字
for i in range(1,last_page+1,1):#判断页面并限制循环次数,每个页面爬取一次
    print ("正在爬取第%s页......\n"% i)
    while i>1:#第一次不执行,停止由最大页数循环控制
        next_page = driver.find_element_by_xpath("//div[@class='pager_container']/span[last()]")#获取下一页按钮
        next_page.click()#点击下一页
        break #跳出while循环
    time.sleep(5) #暂停五秒,注意反爬虫
    source = driver.page_source#获取该网页源码
    html = etree.HTML(source)#解析网页
    works = html.xpath('//*[@id="s_position_list"]/ul/li')#获取每条数据在的节点
    for work in works:        
        position_name = work.xpath("./div[1]/div[1]/div[1]/a/h3/text()")[0] # 职位名称        
        position_url = work.xpath("./div[1]/div[1]/div[1]/a/@href")[0] #详情链接
        # 岗位描述,数组型数据
        desc = work.xpath('./div[2]/div[1]/span/text()')
        desc = str(desc).replace("[","").replace("', '",",").replace("]","").replace("'","")#把数据型转化成字符型才能使用replace替换字符        

        salary = work.xpath("./div[1]/div[1]/div[2]/div/span/text()")[0] #薪资  
        company_name = work.xpath("./div[1]/div[2]/div[1]/a/text()")[0] # 公司名称
        # 岗位需求
        job_request_spans = work.xpath("./div[1]/div[1]/div[2]/div/text()")[-1]
        job_request_spans = str(job_request_spans).replace("\n","").replace(" ","")
        job_experience = job_request_spans.split('/')[0] #截取出工作经验
        education = job_request_spans.split('/')[-1] #截取出学历
        #公司描述
        company_resquest = work.xpath("./div[1]/div[2]/div[2]/text()")[-1]
        company_resquests = str(company_resquest).replace("\n","").replace(" ","")
        company_work = company_resquests.split('/')[0] #截取出公司的工作
        company_resquest = company_resquests.split('/')[1] #截取出公司要求
        company_people = company_resquests.split('/')[-1] #截取出公司人数
        #公司福利
        company_welfare = work.xpath("./div[2]/div[2]/text()")
        if company_welfare != 0:#判断公司是否表明有福利,有则执行条件
            company_welfare = company_welfare[0]
        place = work.xpath("./div[1]/div[1]/div[1]/a/span/em/text()")[0]#获取所在城市位置

        position = (position_name,position_url,desc,salary,company_name,job_experience,education,company_work,company_resquest,company_people,company_welfare,place)
    #         print (position,'\n')

        writer.writerow((position))#写入数据
fp.close() #关闭文件
print ("拉勾网 "+str(city)+"的"+str(major)+"岗位已经获取完毕!")

运行结果:
selenium+lxml爬取(查询)拉勾网职位信息_第5张图片
selenium+lxml爬取(查询)拉勾网职位信息_第6张图片

你可能感兴趣的:(Python实战)