拉勾网登陆后,选择某城市,搜索任意关键字,采集岗位信息数据
起始参考网址:拉勾网
爬虫逻辑:【登陆】-【分页网页url采集】-【访问页面 + 采集岗位信息】
这里按照“数据挖掘”为关键字搜索(注意拉勾网针对不同搜索的关键字网址的结构是不一样的,比如搜索“数据挖掘”和“数据分析”)
比如:以数据挖掘为关键字的搜索(网址会发生变化的)
以“数据分析”为关键字的搜索(网页是不会发生变化的)
1)函数式编程
函数1:login(u,username,password) → 【登陆】
u:起始网址
username:用户名
password:密码
函数2:get_urls(n) → 【分页网页url采集】
这里按照“数据挖掘”关键字
https://www.lagou.com/shanghai-zhaopin/shujuwajue/2/?filterOption=2
https://www.lagou.com/shanghai-zhaopin/shujuwajue/3/?filterOption=3
https://www.lagou.com/shanghai-zhaopin/shujuwajue/4/?filterOption=4
https://www.lagou.com/shanghai-zhaopin/shujuwajue/5/?filterOption=5
n:页数参数
结果:得到一个分页网页的list
函数3:get_data(ui,table) → 【访问页面 + 采集岗位信息】
ui:数据页面网址
table:mongo集合对象
2)采集字段
岗位名称、发布时间、薪资、经验要求、学历要求、企业、行业、融资情况、企业规模,如下
实战讲解
步骤一、前期准备
import re
import time
import pymongo
from selenium import webdriver
if __name__ == '__main__':
browser = webdriver.Chrome()
browser.get("https://www.lagou.com/")
该部分的功能是导入相关的库,和调用各个浏览器进入拉勾网界面,弹出如下窗口
步骤二、进行登录
这里选取全国站,然后进行个人信息登录,过程即是找到各个位置对应的xpath路径,然后click,在需要填写用户名和密码的地方要先清空里面的内容,然后输入自己的信息,如下
browser.find_element_by_xpath('//*[@id="changeCityBox"]/p[1]/a').click()
#选择全国站
browser.find_element_by_xpath('//*[@id="lg_tbar"]/div/div[2]/ul/li[3]/a').click()
#点击登录按钮
user_name = browser.find_element_by_xpath('/html/body/div[2]/div[1]/div/div/div[2]/div[3]/div[1]/div/div[1]/form/div[1]/div/input')
#用户名
pass_word = browser.find_element_by_xpath('/html/body/div[2]/div[1]/div/div/div[2]/div[3]/div[1]/div/div[1]/form/div[2]/div/input')
user_name.clear()
pass_word.clear()
#清空里面的内容
user_name.send_keys('xxx')
pass_word.send_keys('xxx')
#输入个人信息
browser.find_element_by_xpath('/html/body/div[2]/div[1]/div/div/div[2]/div[3]/div[2]/div[2]/div[2]').click()
print(browser.current_url)
#点击登录按钮并返回当前页面的网址
输出的结果为:https://www.lagou.com/(并会弹出验证码,这时候可以使用人工点击的方式,也可以调用api)
步骤三、封装第一个函数
def login(u,username,password):
browser.get(u)
browser.find_element_by_xpath('//*[@id="changeCityBox"]/p[1]/a').click()
#选择全国站
browser.find_element_by_xpath('//*[@id="lg_tbar"]/div/div[2]/ul/li[3]/a').click()
#点击登录按钮
user_name = browser.find_element_by_xpath('/html/body/div[2]/div[1]/div/div/div[2]/div[3]/div[1]/div/div[1]/form/div[1]/div/input')
#用户名
pass_word = browser.find_element_by_xpath('/html/body/div[2]/div[1]/div/div/div[2]/div[3]/div[1]/div/div[1]/form/div[2]/div/input')
user_name.clear()
pass_word.clear()
#清空里面的内容
user_name.send_keys(username)
pass_word.send_keys(password)
#输入个人信息
browser.find_element_by_xpath('/html/body/div[2]/div[1]/div/div/div[2]/div[3]/div[2]/div[2]/div[2]').click()
print(browser.current_url)
#点击登录按钮并返回当前页面的网址
if __name__ == '__main__':
browser = webdriver.Chrome()
login('https://www.lagou.com/', 'xxx','xxx')
这一部分注意用户名和密码对象与传递的参数不要使用完全相同的字符,否则系统无法识别,运行上述代码后会跳出个图片验证码的界面,手动选择即可
步骤四、获取要爬取的url,直接封装第二个函数
通过翻页发现,这些网页有明显的规律,因此可以直接进行封装函数,如下
def get_urls(n):
lst = []
for i in range(1,n+1):
ui = f'https://www.lagou.com/shanghai-zhaopin/shujuwajue/{i}/?filterOption={i}'
lst.append(ui)
return lst
urllst = get_urls(10)
print(urllst)
输出结果为:(经测试每个网址都可以正常打开)
[‘https://www.lagou.com/shanghai-zhaopin/shujuwajue/1/?filterOption=1’,
‘https://www.lagou.com/shanghai-zhaopin/shujuwajue/2/?filterOption=2’,
‘https://www.lagou.com/shanghai-zhaopin/shujuwajue/3/?filterOption=3’,
‘https://www.lagou.com/shanghai-zhaopin/shujuwajue/4/?filterOption=4’,
‘https://www.lagou.com/shanghai-zhaopin/shujuwajue/5/?filterOption=5’,
‘https://www.lagou.com/shanghai-zhaopin/shujuwajue/6/?filterOption=6’,
‘https://www.lagou.com/shanghai-zhaopin/shujuwajue/7/?filterOption=7’,
‘https://www.lagou.com/shanghai-zhaopin/shujuwajue/8/?filterOption=8’,
‘https://www.lagou.com/shanghai-zhaopin/shujuwajue/9/?filterOption=9’,
‘https://www.lagou.com/shanghai-zhaopin/shujuwajue/10/?filterOption=10’]
步骤五、进行相关字段内容的获取并定义第三个函数
首先进行一各字段内容的试错,选取一个页的网址,打开后查找岗位名称(也可以是其他的字段)对应的xpath信息,可是所有的招聘内容都被放在了【ul】标签里面,然后具体的每个招聘信息都是在【li】标签里面,因此要获得岗位字段的内容,可以先定位到【li】标签(当然可以直接定位到岗位字段的标签,属于第二种方式)
browser.get(urllst[0])
ul = browser.find_element_by_xpath('//*[@id="s_position_list"]/ul')
lis = ul.find_elements_by_tag_name('li')
for li in lis:
dic = {}
dic['岗位名称'] = li.find_element_by_tag_name('h3').text
print(dic)
输出的结果为:
那么如果直接采用第二种方式进行爬取数据,所有的信息都是在【li】标签下,因此,每个招聘的岗位对应的【li】标签的序号不同,而每页的招聘数据都是15条,故可以使用如下代码获取岗位名称的信息,如下
for i in range(1,16):
dic ={}
dic['岗位名称'] = browser.find_element_by_xpath(f'//*[@id="s_position_list"]/ul/li[{i}]/div[1]/div[1]/div[1]/a/h3').text
print(dic)
输出结果如下:(和上面的一样,接下来的操作是按照第一种方式进行其他内容的获取,当然也可以按照第二种方式继续)
接着就是获取其它字段的信息了,重点在于info1和info2中的信息获取
for li in lis:
dic = {}
dic['岗位名称'] = li.find_element_by_tag_name('h3').text
dic['发布时间'] = li.find_element_by_class_name('format-time').text
dic['公司名称'] = li.find_element_by_class_name('company_name').text
info1 = re.split(r'[ /]+',li.find_element_by_class_name('li_b_l').text)
dic['薪酬'] = info1[0]
dic['经验水平'] = info1[1]
dic['学历要求'] = info1[2]
info2 = li.find_element_by_class_name('industry').text.split(' / ')
dic['企业类型'] = info2[0]
dic['融资情况'] = info2[1]
dic['公司规模'] = info2[2]
print(dic)
输出的结果为:(截取部分)
接下来就可以配置数据库和进行第三个函数的封装了,首先是进行数据库的设置(数据库的创建与命名以及保存数据的集合)
myclient = pymongo.MongoClient('https://localhost:27017/')
db = myclient['拉勾网数据(1)']
datatable = db['data']
三行代码配置好数据库的问题,接着就是封装第三个函数
def get_datas(u,table):
browser.get(u)
ul = browser.find_element_by_xpath('//*[@id="s_position_list"]/ul')
lis = ul.find_elements_by_tag_name('li')
n = 0
for li in lis:
dic = {}
dic['岗位名称'] = li.find_element_by_tag_name('h3').text
dic['发布时间'] = li.find_element_by_class_name('format-time').text
dic['公司名称'] = li.find_element_by_class_name('company_name').text
info1 = re.split(r'[ /]+',li.find_element_by_class_name('li_b_l').text)
dic['薪酬'] = info1[0]
dic['经验水平'] = info1[1]
dic['学历要求'] = info1[2]
info2 = li.find_element_by_class_name('industry').text.split(' / ')
dic['企业类型'] = info2[0]
dic['融资情况'] = info2[1]
dic['公司规模'] = info2[2]
table.insert_one(dic)
n += 1
return n
接着就是程序的运行函数和错误异常处理以及输出可视化的过程了
data_count = 0
error_lst = []
for u in urllst:
try:
data_count += get_datas(u,datatable)
sleep_time = random.randint(1,5)
print(f'已爬取并收集{data_count}条数据')
print('休眠时间中......',sleep_time)
time.sleep(sleep_time)
except:
error_lst.append(u)
print('数据爬取失败,该网址为:',u)
最终的运行及输出结果如下
数据库中的数据如下:(部分截图)