selelinum+PhantomJS 爬取拉钩网职位
使用selenium+PhantomJS爬取拉钩网职位信息,保存在csv文件至本地磁盘
拉钩网的职位页面,点击下一页,职位信息加载,但是浏览器的url的不变,说明数据不是发送get请求得到的。
我们不去寻找它的API。这里使用另一种方式:使用PhantomJS模拟浏览,通过单击页面获取下一页。
这里的PhantomJS是一个没有界面的浏览器。
1 from selenium import webdriver 2 import time 3 import random 4 5 from selenium.webdriver.common.by import By 6 from selenium.webdriver.support import expected_conditions as EC 7 from selenium.webdriver.support.ui import WebDriverWait 8 9 ''' 10 使用selenium+PhantomJS爬取拉钩网职位信息,保存到csv文件至本地磁盘 11 需要加请求头 12 ''' 13 14 15 ''' 16 phantomjs.page.customHeaders. :自定义请求头的固定写法 17 如:定义代理:phantomjs.page.customHeaders.User-Agent 18 ''' 19 dc = { 20 'phantomjs.page.customHeaders.User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36' 21 } 22 23 # 创建浏览器对象 24 browser = webdriver.PhantomJS(executable_path=r'E:\PycharmProjects\pachong\phantomjs-2.1.1-windows\phantomjs-2.1.1-windows\bin\phantomjs.exe',desired_capabilities=dc) 25 26 # 发送请求 27 browser.get('https://www.lagou.com/jobs/list_?labelWords=&fromSearch=true&suginput=') 28 time.sleep(2) 29 30 # 保存网页截图 31 browser.save_screenshot('lagou.png') 32 33 # 实例化wait对象 设置等待超时时间为20秒 34 wait = WebDriverWait(browser,20) 35 36 # # 创建csv文件 37 f = open('lagou.csv','w',encoding='utf-8') 38 39 while True: 40 # 获取数据 41 job_list = browser.find_elements_by_css_selector('.item_con_list li') 42 for job in job_list: 43 pname = job.find_element_by_tag_name('h3').text 44 ptime = job.find_element_by_class_name('format-time').text 45 company = job.find_element_by_css_selector('.company_name a').text 46 money = job.find_element_by_class_name('money').text 47 exp = job.find_element_by_class_name('li_b_l').text.split(' ')[1] #这里的text不取div里面的标签的内容,只取div中的内容。类名为li_b_l的div有两个,经验属于第二个,还有一个工作要求的 48 location = job.find_element_by_tag_name('em').text 49 reqtags = job.find_elements_by_css_selector('.li_b_l span') #div的类是li_b_l,里面含有很多span标签.会把工资的那一个也包含进来,后面需要处理 50 reqtags = ' '.join([reqtag.text for reqtag in reqtags][1:]) #每个条目的第一项是工资的那个,这里使用列表的切片去掉。 51 52 # 将数据放入一个列表,便于后面csv文件格式处理,使用,隔开每一项 53 data = [pname,ptime,company,money,exp,location,reqtags] 54 # print(data) 55 f.write(','.join(data) + '\n') 56 57 print(data) 58 if 'pager_next pager_next_disabled' not in browser.page_source: 59 # 获取下一页按钮 60 wait.until(EC.element_to_be_clickable((By.CLASS_NAME,'pager_next '))) #原网页中的类的最后有一个空格 61 # 点击进入下一页 62 browser.find_element_by_class_name('pager_next ').click() 63 time.sleep(3 + random.random()*1) #时间需要延长一点,时间太短,页面没有加载完成,获取数据会报错 64 else: 65 break 66 67 # 关闭文件 68 f.close()
selelinum+PhantomJS 爬取拉钩网职位2
上面的代码中,使用selenium中的方法提取网页中的数据,有部分功能不好用,延时比较厉害。这里使用bs4提取网页中的数据,速度较快。
1 from selenium import webdriver 2 import time 3 import re 4 import random 5 from selenium.webdriver.common.by import By 6 from selenium.webdriver.support import expected_conditions as EC 7 from selenium.webdriver.support.ui import WebDriverWait 8 from bs4 import BeautifulSoup 9 ''' 10 selenium+Chrome 抓取拉钩网职位 11 使用xpath bs4解析。 12 ''' 13 14 browser = webdriver.Chrome(executable_path=r'E:\PycharmProjects\pachong\chromedriver.exe') 15 browser.get('https://www.lagou.com/jobs/list_?labelWords=&fromSearch=true&suginput=') 16 time.sleep(2) 17 f = open('lagou2.csv',mode='w',encoding='utf-8') 18 19 #设置等待超时时间为20秒 20 wait = WebDriverWait(browser,20) 21 22 23 # #使用Chrome驱动的提供的方法查找网页元素,在这里使用列表的分页,有延时 24 # while True: 25 # # 获取数据 26 # job_list = browser.find_elements_by_css_selector('.item_con_list li') 27 # for job in job_list: 28 # pname = job.find_element_by_tag_name('h3').text 29 # ptime = job.find_element_by_class_name('format-time').text 30 # company = job.find_element_by_css_selector('.company_name a').text 31 # money = job.find_element_by_class_name('money').text 32 # exp = job.find_element_by_class_name('li_b_l').text.split(' ')[1] #这里的text不取div里面的标签的内容,只取div中的内容。类名为li_b_l的div有两个,经验属于第二个,还有一个工作要求的 33 # location = job.find_element_by_tag_name('em').text 34 # reqtags = job.find_elements_by_css_selector('.li_b_l span') #div的类是li_b_l,里面含有很多span标签.会把工资的那一个也包含进来,后面需要处理 35 # reqtags = ' '.join([reqtag.text for reqtag in reqtags][1:]) #每个条目的第一项是工资的那个,这里使用列表的切片去掉。 36 # 37 # # 将数据放入一个列表,便于后面csv文件格式处理,使用,隔开每一项 38 # data = [pname,ptime,company,money,exp,location,reqtags] 39 # # print(data) 40 # f.write(','.join(data) + '\n') 41 # 42 # print(data) 43 # if 'pager_next pager_next_disabled' not in browser.page_source: 44 # # 获取下一页按钮 45 # wait.until(EC.element_to_be_clickable((By.CLASS_NAME,'pager_next '))) #原网页中的类的最后有一个空格 46 # # 点击进入下一页 47 # browser.find_element_by_class_name('pager_next ').click() 48 # time.sleep(3 + random.random()*1) #时间需要延长一点,时间太短,页面没有加载完成,获取数据会报错 49 # else: 50 # break 51 52 53 54 while True: 55 # 获取数据 56 57 wait.until(EC.presence_of_element_located((By.CLASS_NAME,'item_con_list'))) #等待职位信息加载 58 59 html = browser.page_source 60 html = BeautifulSoup(html,'lxml') 61 job_list = html.select('ul[class="item_con_list"] li') 62 63 for job in job_list: 64 pname = job.h3.text 65 ptime = job.select('span[class="format-time"]')[0].text 66 company = job.select('div[class="company_name"] a')[0].text 67 money = job.select('span[class="money"]')[0].text 68 exp = job.select('div[class="li_b_l"]')[0].text 69 exp = re.split('\s',exp)[2] #使用正则切割 \s匹配所有空白,这里主要匹配 空格 和 \n。第三项是工作经验 70 71 location = job.select('span[class="add"] em')[0].text 72 73 tags = job.select('div[class="li_b_l"] span') #tags 匹配出匹配出两部分,一部分是薪资,一部分是工作要求,后面进行过滤后只要工作要求 74 tag_list = [tag.text for tag in tags[1:]] #这里过滤掉薪资数据,只留下工作要求 75 76 # print(tag_list) 77 tags = ' '.join(tag_list) 78 data = [pname,ptime,company,money,exp,location,tags] 79 print(data) 80 81 f.write(','.join(data) + '\n') 82 83 if 'pager_next_disabled' not in browser.page_source: 84 # 获取下一页 85 wait.until(EC.element_to_be_clickable((By.CLASS_NAME,'pager_next'))) 86 browser.find_element_by_class_name('pager_next').click() 87 time.sleep(1+random.random()) #延时太短可能加载未完成。抓取页面数据程序会报错,在开头检测职位加载等待,这里时间可以少一点。 88 else: 89 break 90 91 f.close()