Ps : 随着一代代的先辈爬虫和拉钩的攻防战,这一场惨烈的攻防战,双方的军备竞赛不断升级。好了,轮到我上场的时候,之前的爬取方式,无论是传统的发送HTTP请求返回网页源码,还是动态页面访问数据接口都已经失效。我只好使用终极大杀器selenium+phantomjs,模拟人使用浏览器访问网站的方式
环境配置
- selenium
pip install selenium
建议大家安装 selenium2 版本,因为3.x的版本好像不支持PhantomJS - PhantomJS
官方网址:http://phantomjs.org/ , 下载解压后,把bin目录下phantomjs的路径加入环境变量
简单的介绍下:selenium是python的一个第三方自动化测试库可以模拟人的操作。selenium下的webdriver子包支持市面上几乎所有的主流浏览器,同时也支持PhantomJS这种无界面浏览器。
代码预览
from lxml import etree
from pymongo import MongoClient
import pymongo.errors
import traceback
import re
import time
from selenium import webdriver
# 引入配置对象DesiredCapabilities
from selenium.webdriver.common.desired_capabilities import DesiredCapabilities
#设置头部信息
dcap = dict(DesiredCapabilities.PHANTOMJS)
dcap['phantomjs.page.settings.userAgent'] = (
'Mozilla/5.0 (Windows NT 10.0; WOW64; rv:53.0) Gecko/20100101 Firefox/53.0'
)
driver = webdriver.PhantomJS(desired_capabilities=dcap)
driver.get('https://www.lagou.com/zhaopin/Python/?labelWords=label')
#连接数据库
def dbConnect():
try:
client = MongoClient()
db = client.lagou
except Exception as e:
print("mongodb Error:", e)
traceback.print_exc()
return db
# 自定义分割字符串函数
def sp(list1,list2,news):
for x in news:
if x.strip()!='':
list1.append(x.split('/')[0].strip())
list2.append(x.split('/')[1].strip())
db = dbConnect()
collection = db.reinformation
#页面计数,拉钩最多查看30页
count = 1
while True:
# 在这里我没有使用selenium自带的xpath定位方法,而是使用lxml库的xpath定位方法
html = driver.page_source
selector=etree.HTML(html)
#获取所需信息
ids=selector.xpath('//div[@class="company_name"]/a/@href')
company=selector.xpath('//div[@class="company_name"]/a/text()')
job =selector.xpath('//a[@class="position_link"]/h3/text()')
address =selector.xpath('//span[@class="add"]/em/text()')
temp1 =selector.xpath('//div[@class="p_bot"]/div[@class="li_b_l"]/text()')
salary = selector.xpath('//span[@class="money"]/text()')
temp2 = selector.xpath('//div[@class="industry"]/text()')
treatment = selector.xpath('//div[@class="li_b_r"]/text()')
industry = []
scale = []
experience = []
education = []
sp(experience,education,temp1)
sp(industry,scale,temp2)
#把mongodb的集合中为了去重主键自定义为公司ID,在mongodb中主键一般都是自己生成的,
# 这样做反而插入速度大大降低,更适合关系型数据库Mysql
ids = list(map(lambda x: re.findall(r'\d+',x)[0], ids))
keys = ['_id','company','job', 'address', 'salary', 'experience', 'education', 'industry', 'scale', 'treatment']
for li in zip(ids,company,job,address,salary,experience,education,industry,scale,treatment):
try:
collection.insert_one(dict(zip(keys, li)))
except pymongo.errors.DuplicateKeyError:
pass
else:
print('招聘公司:%s' % li[1])
print('第 %s 页写入完毕' % count)
count += 1
if count == 30:
print('全部写入完毕')
break
# 访问下一页
driver.find_element_by_link_text("下一页").click()
time.sleep(2)
driver.quit()
好了,数据爬取完毕,部分数据截图如下:
这是截的pycharm上的Mongo插件显示的数据图,如果需要的同学可以看这里: 有哪些Mongo可视化工具
代码总结
以上只是一个粗糙的拉钩爬虫代码,还有很多不足之处,包括
- 爬取的信息较少,没有具体的招聘信息
- 使用单线程,速度较慢
- 没有自动化批量爬取
以上代码仅供学习使用,代码地址:
https://github.com/daocaoren1111/lagouspider