使用selenium爬取拉勾网数据分析职位信息并存储到MongoDB
程序员文章站
2022-04-28 09:02:43
...
使用selenium爬取拉勾网数据分析职位信息并存储到MongoDB
工具:Chromedriver,Google浏览器,selenium,MongoDB
1.首先分析拉勾网页信息知道它的职位信息放在ajax链接里
但是拉勾的反爬机制使我们不能直接从ajax链接获取职位信息,会出现以下信息:
{“status”:false,“msg”:“您操作太频繁,请稍后再访问”,“clientIp”:“113.227.30.199”,“state”:2402}
所以选择使用selenium通过模拟浏览器获取信息。
2.通过selenium运行浏览器访问拉勾网首先会出现一个选取城市分站的小窗口,这里使用css选择器模拟选择全国选项
3.这时候进入到拉勾网主站页面,要做的是使浏览器在搜索框自动输入‘数据分析’然后点击搜索框
4.这是进入拉勾首页并搜索数据分析的代码
try:
browser.get('https://www.lagou.com')
sub=wait.until(ECD.element_to_be_clickable((By.CSS_SELECTOR,'#changeCityBox > p.checkTips > a')))
sub.click()
input=wait.until(ECD.presence_of_element_located((By.CSS_SELECTOR,'#search_input')))
submit=wait.until(ECD.element_to_be_clickable((By.CSS_SELECTOR,'#search_button')))
input.send_keys('数据分析')
submit.click()
get_jobs()
except TimeoutException:
return search()
5.下面要解决的是翻页问题,这里通过使用css选择器模拟选取页面里的下一页按钮
def next_page():
try:
submit=wait.until(ECD.element_to_be_clickable((By.CSS_SELECTOR,'#s_position_list > div.item_con_pager > div > span.pager_next')))
submit.click()
get_jobs()
except TimeoutException:
next_page()
6.接下来分析页面内每个职位的信息
以这个职位信息为例,要爬取的信息有职位名称,城市,职位标签,公司名称,公司标签以及公司福利信息,使用pyquery解析网页源码,同样使用css选择器从里面提取出各种职位信息
def get_jobs():
wait.until(ECD.presence_of_element_located((By.CSS_SELECTOR,'#s_position_list .item_con_list .con_list_item.default_list ')))
html=browser.page_source
doc=pq(html)
items=doc('#s_position_list .item_con_list .con_list_item.default_list').items()
for item in items:
job={
'job':item.find('div.list_item_top > div.position > div.p_top > a > h3').text(),
'position':item.find('div.list_item_top > div.position > div.p_top > a > span > em').text(),
'salary':item.find('div.list_item_top > div.position > div.p_bot > div > span').text(),
'experience':item.find('div.list_item_top > div.position > div.p_bot').text(),
'company':item.find('div.list_item_top > div.company > div.company_name > a').text(),
'companytag':item.find('div.list_item_top > div.company > div.industry').text(),
'jobtag':item.find('div.list_item_bot > div.li_b_l > span').text(),
'welfare':item.find('div.list_item_bot > div.li_b_r').text()
}
print(job)
save_to_mongo(job)
7.爬取完数据之后调用MongoDB存储职位信息
#定义MongoDB
MONGO_URL='localhost:27017'
MONGO_DB='Job'
MONGO_TABLE='DataAnalyze'
def save_to_mongo(result):
try:
if db[MONGO_TABLE].insert(result):
print('存储成功',result)
except Exception:
print('存储失败',result)
8.下面贴上完整代码,
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.support import expected_conditions as ECD
from selenium.webdriver.support.ui import WebDriverWait
from selenium.common.exceptions import TimeoutException
from pyquery import PyQuery as pq
import urllib.error
import pymongo
from pymongo import MongoClient
MONGO_URL='localhost:27017'
MONGO_DB='Job'
MONGO_TABLE='DataAnalyze'
client = MongoClient(MONGO_URL)
db=client[MONGO_DB]
chromeOptions=webdriver.ChromeOptions()
chromeOptions.add_argument('--proxy-server=http://113.142.69.69:16816') #设置代理
browser = webdriver.Chrome(chrome_options=chromeOptions)
wait=WebDriverWait(browser,10)
def save_to_mongo(result):
try:
if db[MONGO_TABLE].insert(result):
print('存储成功',result)
except Exception:
print('存储失败',result)
def search():
try:
browser.get('https://www.lagou.com')
sub=wait.until(ECD.element_to_be_clickable((By.CSS_SELECTOR,'#changeCityBox > p.checkTips > a')))
sub.click()
input=wait.until(ECD.presence_of_element_located((By.CSS_SELECTOR,'#search_input')))
submit=wait.until(ECD.element_to_be_clickable((By.CSS_SELECTOR,'#search_button')))
input.send_keys('数据分析')
submit.click()
get_jobs()
except TimeoutException:
return search()
def next_page():
try:
submit=wait.until(ECD.element_to_be_clickable((By.CSS_SELECTOR,'#s_position_list > div.item_con_pager > div > span.pager_next')))
submit.click()
get_jobs()
except TimeoutException:
next_page()
def get_jobs():
wait.until(ECD.presence_of_element_located((By.CSS_SELECTOR,'#s_position_list .item_con_list .con_list_item.default_list ')))
html=browser.page_source
doc=pq(html)
items=doc('#s_position_list .item_con_list .con_list_item.default_list').items()
for item in items:
job={
'job':item.find('div.list_item_top > div.position > div.p_top > a > h3').text(),
'position':item.find('div.list_item_top > div.position > div.p_top > a > span > em').text(),
'salary':item.find('div.list_item_top > div.position > div.p_bot > div > span').text(),
'experience':item.find('div.list_item_top > div.position > div.p_bot').text(),
'company':item.find('div.list_item_top > div.company > div.company_name > a').text(),
'companytag':item.find('div.list_item_top > div.company > div.industry').text(),
'jobtag':item.find('div.list_item_bot > div.li_b_l > span').text(),
'welfare':item.find('div.list_item_bot > div.li_b_r').text()
}
print(job)
save_to_mongo(job)
def main():
search()
for i in range(2,31):
print('当前正在获取第'+str(i)+'页')
next_page()
browser.close()
if __name__ == "__main__":
main()
9.下面是爬取结果示例
这里exprience工作经验项带了薪水信息,可以在用split()函数切片提取后面的经验信息,不过我在这里没进行处理。
10.将MongoDB数据导出为csv格式文件,在Excel对它进行进一步处理,下面是处理后的结果
11.将Excel文件导入到tableau,取最高薪资、最低薪资、平均薪资((最高薪资+最低薪资)/2)的中位数,以平均薪资中位数由高到低排列,可以看出全国里北京的平均薪资是最高的。