百度百聘爬取详细分析
这两天我一直在爬取百度百聘这个招聘网站,里面的工作还是很多的,都是从其他招聘网站上获取下来了 下面我就给大家详细分析一下这次我在百度百聘爬取时的思路和遇到的问题 和 解决办法提供大家参考:
爬取数据的思路:
1.找到存有数据的链接
2. 分析获取数据的链接 需要 城市 数据起始位置 token
3. 获取所有的城市
4. 解密token 获取
5. 进行模拟登录 然后保持session会话
6. 获取所有的数据
首先我们进入百度百聘的网站主页:
https://zhaopin.baidu.com/quanzhi?city=%E5%8C%97%E4%BA%AC
然后打开检查模式:
我们发现他里面的数据是通过json数据返回给页面展示出来的 而且是通过滑动来不断的获取数据 我们滑动数据来找出来他返回数据的链接:
通过分析:pn是返回数据的其实位置-rn是每次返回的数据个数
接下来我们的目标就就是获取 json数据 然后从json数据中获取我们需要的 有用数据
我们来分析请求json数据的链接 :
是通过https://zhaopin.baidu.com/api/qzasync?+
这几个数据拼成的链接请求出来的
现在的思路是通过改变城市和pn的起始位置,拼接链接来请求所有的json数据:
1:获取所有的城市:
self.driver = webdriver.Chrome()
self.html_all=self.driver.get('https://zhaopin.baidu.com/')
#获取所有的def all_city(self):city = self.html_all.xpath(r'//a[@class="city"]/text()')city_list = [i for i in set(city)]print(city_list)self.wither(city_list)def wither(self, data):with open('city.txt', 'w') as f:f.write('-'.join(data))
2.遍历所有城市,拼接链接来请求json数据:
def read(self):with open('city.txt', 'r') as f:h = f.read()j = h.split('-')return jdef data_dict(self, city, num, token):data = {"query": "python","city": city,"is_adq": "1","pcmod": "1","token": ‘==QmS/6qT2apUZInspZZtV5ZemWlJaoaiFnZkF2mshmZ’,"pn": num,"rn": "20"}return datadef request_html(self):for city in self.read():while True:f = self.data_dict(city, self.num)h = parse.urlencode(f)l = self.url + hprint(l)data = requests.get(l, ti meo5,).content.decode('utf-8')dif len(data) < 5000:breakdata_json = json.loads(data)for i in range(20):try:company_name = data_json['data']['disp_data'][i]['company']start = data_json['data']['disp_data'][i]['requirements']number = data_json['data']['disp_data'][i]['number']try:good1 = data_json['data']['disp_data'][i]['welfare']good = '-'.join(good1)except Exception as e:good = '目前没有优势'day = data_json['data']['disp_data'][i]['lastmod']manny = data_json['data']['disp_data'][i]['salary']url = data_json['data']['disp_data'][i]['pc_url']name = data_json['data']['disp_data'][i]['title']# mess = data_json['data']['disp_data'][i]['companydescription']direction = data_json['data']['disp_data'][i]['first_level_label']companytype = data_json['data']['disp_data'][i]['employertype']city = data_json['data']['disp_data'][i]['location']# print(self.count, company_name, start, number, day, manny, good, url, name)print(company_name, start.strip('要求: '), direction)self.count += 1list2 = [url, name, company_name, manny, city, number, start.strip('要求: '), companytype,direction, good + day]self.writ_csv(list2)except Exception as e:print(e)continueself.num += 20self.num = 0
在请求了几次json数据后我发现后面请求回来的不是json数据 而是百度的登录页面:
这也就意味这我们要想持续的获取数据 我们就必须进行模拟登录 然后保持session:
def selenum_login(self):self.driver.get(url)time.sleep(2)self.driver.find_element_by_id('TANGRAM__PSP_3__footerULoginBtn').click()time.sleep(3)self.driver.find_element_by_name('userName').send_keys('18191042297')self.driver.find_element_by_name('password').send_keys('Fwm802311')self.driver.find_element_by_id('TANGRAM__PSP_3__submit').click()time.sleep(3)def get_session(self):self.html_selenium('https://passport.baidu.com/v2/?login&sms=1&u=https%3A%2F%2Fzhaopin.baidu.com%2Fquanzhi%3Fcity%3D%25E5''%258C%2597%25E4%25BA%25AC%26query%3Dpython')self.selenum_login()time.sleep(60)# f = self.data_dict('北京', self.num, '==QmQztqVO70FyFlrpZbbaWawdpaVhIlq9WZmpJaYa2k')# h = parse.urlencode(f)# self.driver.get(self.url + h)self.driver.get('https://zhaopin.baidu.com/quanzhi?city=%E5%8C%97%E4%BA%AC')cookies = self.driver.get_cookies()return cookies#判断session是否获取过 如果获取过 就读取文件 如果没有获取过 是第一次 那就通过模拟登录来获取cookies然后写入文件 def use_session(self):if not os.path.exists('session.txt'):self.session.headers.clear()self.session_city.headers.clear()for cook in self.get_session():self.session.cookies.set(cook['name'], cook['value'])for cook_city in self.get_session_city():self.session_city.cookies.set(cook_city['name'], cook_city['value'])self.save_session(self.session, 'session')self.save_session(self.session_city, 'session_city')else:self.session = self.load_session('session')self.session_city = self.load_session('session_city')self.driver.close()
3.,没错 我有遇到了问题 就是我发现每次请求数据的json链接中的token每个城市 和过会时间是会改变的 我们现在就要破解token:
就是在你登录请求的的第一个页面里的下面的值
data[“nekot”] = “lGSYaphoYW1jl4hVapdwaWaaapVvmFyF07OVqtzQmQ==”;
进行了如下变换
说白了就是Python中讲字符串倒序输出了
解决思路:
每次请求这个网址https://zhaopin.baidu.com/quanzhi?city= 城市 ,也就是说请求每个城市的职位时,或者这个网页中的这个值 data[“nekot”] = “lGSYaphoYW1jl4hVapdwaWaaapVvmFyF07OVqtzQmQ==”;
然后对这个值进行倒序输出,转换成token值
最后拼接参数发送请求
最后我们解决了所有问题可以开始爬取数据了:
全代码:
import csv
import json
import os
import pickle
import re
import time
from urllib import parse
import threading
import requests
from bs4 import BeautifulSoup
from fake_useragent import UserAgent
from selenium import webdriverclass Baipin(object):def __init__(self):# threading.Thread.__init__(self)self.session = requests.Session()self.session_city = requests.Session()self.html_all = ''self.url = 'https://zhaopin.baidu.com/api/qzasync?'self.url1 = 'https://zhaopin.baidu.com/quanzhi?'self.driver = webdriver.Chrome()self.headers = {'User-Agent': UserAgent().random}self.all_headers = {'Cookie': 'ZP_FLAG=12; Hm_lvt_da3258e243c3132f66f0f3c247b48473=1583858066,1583858672,1583859396,''1583860201; Hm_lpvt_da3258e243c3132f66f0f3c247b48473=1583860201; ''BAIDUID=22233072050588D1C8EA78ACBFEAFDEE:FG=1; PSTM=1583861696; ''BDORZ=B490B5EBF6F3CD402E515D22BCDA1598; ''BDUSS=Vd2c09ZT2w3Y3Y0LTZkd2d0YVY4RHYyUTU2RU1nWTNoTUtsNWFOQ34weG1''-bzllRUFBQUFBJCQAAAAAAQAAAAEAAACZEq8CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGZxaF5mcWhec; BIDUPSID=22233072050588D1C8EA78ACBFEAFDEE; delPer=0; PSINO=7; H_PS_PSSID=30970_1455_21111_30841_30794_30998_30824_26350',"User-Agent": UserAgent().random}self.num = 0self.count = 0self.proxies = {'https': 'https://113.194.31.123:9999'}# self.city=city# def run(self):## self.request_html(city=self.city)def __call__(self, *args, **kwargs):pass# self.html_selenium('https://zhaopin.baidu.com/?query=&city=%E5%A4%A9%E6%B4%A5')# self.all_city()# self.read()# self.html_request('https://zhaopin.baidu.com/quanzhi?query=python&city=%E4%B8%8A%E6%B5%B7')# self.test()# self.renren()# self.request_html()# print(UserAgent().random)#self.use_session()# self.get_token('北京')print('开始获取数据')# self.driver.close()self.request_html()# self.request_html()# self.selenum_data('https://zhaopin.baidu.com/api/qzasync?query=&city=%E5%8C%97%E4%BA%AC&is_adq=1&pcmod=1&token=%3D%3Dgxjud2E7tqaZIbZypaW6GlvhWZZdFmptWZmlZmYiZl&pn=20&rn=20')def save_session(self, session, name):with open(f'{name}.txt', 'wb') as f:pickle.dump(session, f)print('写入session成功')def load_session(self, name):with open(f'{name}.txt', 'rb') as f:s = pickle.load(f)return sdef get_session(self):self.html_selenium('https://passport.baidu.com/v2/?login&sms=1&u=https%3A%2F%2Fzhaopin.baidu.com%2Fquanzhi%3Fcity%3D%25E5''%258C%2597%25E4%25BA%25AC%26query%3Dpython')self.selenum_login()time.sleep(60)# f = self.data_dict('北京', self.num, '==QmQztqVO70FyFlrpZbbaWawdpaVhIlq9WZmpJaYa2k')# h = parse.urlencode(f)# self.driver.get(self.url + h)self.driver.get('https://zhaopin.baidu.com/quanzhi?city=%E5%8C%97%E4%BA%AC')cookies = self.driver.get_cookies()return cookiesdef get_session_city(self):self.html_selenium('https://zhaopin.baidu.com/quanzhi?query=&city=%E5%8C%97%E4%BA%AC')cookies = self.driver.get_cookies()return cookiesdef use_session(self):if not os.path.exists('session.txt'):self.session.headers.clear()self.session_city.headers.clear()for cook in self.get_session():self.session.cookies.set(cook['name'], cook['value'])for cook_city in self.get_session_city():self.session_city.cookies.set(cook_city['name'], cook_city['value'])self.save_session(self.session, 'session')self.save_session(self.session_city, 'session_city')else:self.session = self.load_session('session')self.session_city = self.load_session('session_city')self.driver.close()def session_json(self, url):data = self.session.get(url).content.decode('utf-8')return datadef html_selenium(self, url):self.driver.get(url)time.sleep(2)def selenum_login(self):self.driver.find_element_by_id('TANGRAM__PSP_3__footerULoginBtn').click()time.sleep(3)self.driver.find_element_by_name('userName').send_keys('18191042297')self.driver.find_element_by_name('password').send_keys('Fwm802311')self.driver.find_element_by_id('TANGRAM__PSP_3__submit').click()time.sleep(3)def get_token(self, city):data_dict = {"city": city}data = self.session_city.get(url=self.url1, data=data_dict, timeout=5, stream=True).content.decode('utf-8')token1 = re.findall(r'"nekot"] = "([\s\S]+?)";', data)[0]# print(token1)token = token1[::-1]return tokendef selenum_data(self, url):try:self.driver.get(url)data = self.driver.page_source# data1=json.loads(data)# da=data.e# print(data)soup = BeautifulSoup(data, 'lxml')cc = soup.select('pre')[0]h = cc.textexcept Exception as e:print(e)h = 'hello'return hdef html_request(self, url):data = requests.get(url=url, headers=self.all_headers).content.decode('utf-8')print(data)def request_html(self):for city in self.read():while True:time.sleep(3)try:token = self.get_token(city)f = self.data_dict(city, self.num, token)h = parse.urlencode(f)l = self.url + hprint(l)# data = self.html_selenium(self.url+h) data = requests.get(url=self.url + h,# headers=self.all_headers,allow_redirects=False).content.decode('utf-8')data = self.session.get(l, timeout=5,).content.decode('utf-8')except Exception as e:print(e)continueif len(data) < 5000:breaktry:data_json = json.loads(data)except Exception as e:print(e)continuefor i in range(20):try:company_name = data_json['data']['disp_data'][i]['company']start = data_json['data']['disp_data'][i]['requirements']number = data_json['data']['disp_data'][i]['number']try:good1 = data_json['data']['disp_data'][i]['welfare']good = '-'.join(good1)except Exception as e:good = '目前没有优势'day = data_json['data']['disp_data'][i]['lastmod']manny = data_json['data']['disp_data'][i]['salary']url = data_json['data']['disp_data'][i]['pc_url']name = data_json['data']['disp_data'][i]['title']# mess = data_json['data']['disp_data'][i]['companydescription']direction = data_json['data']['disp_data'][i]['first_level_label']companytype = data_json['data']['disp_data'][i]['employertype']city = data_json['data']['disp_data'][i]['location']# print(self.count, company_name, start, number, day, manny, good, url, name)print(company_name, start.strip('要求: '), direction)self.count += 1list2 = [url, name, company_name, manny, city, number, start.strip('要求: '), companytype,direction, good + day]self.writ_csv(list2)except Exception as e:print(e)continueself.num += 20self.num = 0def all_city(self):city = self.html_all.xpath(r'//a[@class="city"]/text()')city_list = [i for i in set(city)]print(city_list)self.wither(city_list)def wither(self, data):with open('city.txt', 'w') as f:f.write('-'.join(data))def test(self):h = parse.urlencode('上海')print(h)def data_dict(self, city, num, token):data = {"query": "python","city": city,"is_adq": "1","pcmod": "1","token": token,"pn": num,"rn": "20"}return datadef renren(self):url = 'https://passport.baidu.com/v2/?login&sms=1&u=https%3A%2F%2Fzhaopin.baidu.com%2F'head = {'username': '18191042297','password': 'Fwm802311'}def writ_csv(self, list1):with open("test.csv", "a+",encoding='GB18030') as csvfile:writer = csv.writer(csvfile)# 先写入columns_name# 写入多行用writerowswriter.writerow(list1)def read(self):with open('city.txt', 'r') as f:h = f.read()j = h.split('-')return j[:48]# class Tencent(threading.Thread, Baipin):
# def __init__(self, city):
# threading.Thread.__init__(self)
# self.city = cityif __name__ == '__main__':print('开始获取数据')pin = Baipin()pin()
在这次爬取过程中我还遇到了许多的小问题:
- 在请求数据中有时候就卡在哪里一直不懂 请求不下来数据
解决办法:我们给每次请求加上时间 如果请求过了时间就报错 然后我们用异常处理来扑捉,如果扑捉到超时 我们就重新请求
try:data = self.session.get(l, timeout=5,).content.decode('utf-8')
except Exception as e:print(e)continue
- 在我们用selenum请求json数据的时候返回来的数据不是纯json数据 是整个网页的html文件json数据包含在其中我们取出来很麻烦
解决办法:
from bs4 import BeautifulSoup
self.driver.get(url)#data获取到的json网页信息data = self.driver.page_source# data1=json.loads(data)# da=data.e# print(data)soup = BeautifulSoup(data, 'lxml')cc = soup.select('pre')[0]h = cc.text#h是取出来的json数据
- url需要转译才可以请求:
from urllib import parsedef data_dict(self, city, num, token):data = {"query": "python","city": city,"is_adq": "1","pcmod": "1","token": token,"pn": num,"rn": "20"}return datah = parse.urlencode(data)#h就是编译好的数据
整个的爬取过程就是这个情况,希望对大家有所帮助,有更好的办法欢迎大家评论,互相学习!
百度百聘爬取详细分析相关推荐
- python爬去新浪微博_荐爬虫实战 新浪微博爬取 详细分析
目标 #2020.5.22 #author:pmy #目标:爬取最爱的绵羊的微博,包含时间,文本内容,点赞数,评论数与转发数 #在更换博主时主要在于修改headers中的referer和参数中的con ...
- 【Python课程作业】食物数据的爬取及分析(详细介绍及分析)
食物数据爬取及分析 项目概述 网页爬取 食物类别 表头设置 食物数据爬取保存 运行结果 数据分析 CSV文件读取 总体描述 分类分析 特定食物分析 运行结果 项目资源 项目概述 日常生活中我们食用的各 ...
- 百度百聘企业简单信息获取
百度百聘企业简单信息获取 背景 思路 完整代码 代码解析 改进思路 免责声明 背景 现在企业工商信息都互联网化了,企查查,天眼查和启信宝就是专门做这个,但是这三位都不是省油的灯,网页相似的一匹马,且保 ...
- python数据爬取、分析与内容审核基于PaddlePaddle
这次要做的就是分四步完成爬取评论数据并进行可视化的评论内容分析.先展示一下预期效果 第一步:爱奇艺<青春有你2>评论数据爬取(参考链接:https://www.iqiyi.com/v_19 ...
- 网上租房数据的爬取与分析
主要介绍租房书爬取与分析过程中用到的相关技术,爬虫所用开发语言为python,开发环境anaconda,用beautifulsoup解析网页,数据处理numpy,可视化展示matplotlib,所用数 ...
- 网络爬虫分析实例:基于音悦台网站榜单的数据爬取与分析
基于音悦台网站榜单的数据爬取与分析 本实验代码:进入 一.研究背景 在互联网发展初期,网站相对较少,信息查找比较容易.然而伴随互联网爆炸性的发展,普通网络用户想找到所需的资料简直如同大海捞针,这时为满 ...
- python爬百度新闻_13、web爬虫讲解2—Scrapy框架爬虫—Scrapy爬取百度新闻,爬取Ajax动态生成的信息...
crapy爬取百度新闻,爬取Ajax动态生成的信息,抓取百度新闻首页的新闻rul地址 有多网站,当你浏览器访问时看到的信息,在html源文件里却找不到,由得信息还是滚动条滚动到对应的位置后才显示信息, ...
- 最没灵魂的爬虫——Selenium 游戏信息的爬取与分析
最没有灵魂的爬虫--Selenium 游戏信息爬取与分析 准备工作 IDE选取 selenium安装 ChromeDriver安装与配置 还需要用到的其他python库 数据爬取 杉果游戏的数据获取 ...
- python微博爬虫分析_python爬取和分析新浪微博(一):scrapy构建新浪微博榜单、博主及微博信息爬虫...
1. 爬虫项目介绍 爬虫首先基于python scrapy 框架,使用了随机用户代理和IP代理等反爬技巧,将爬取到的微博领域数据,各领域榜单博主信息和博主的微博信息分别存入的mysql数据库对应的表格 ...
最新文章
- jgit查询远程仓库_JAVA 使用jgit管理git仓库
- 【mybatis】在mybatis分页查询时,主表对关联表 一对多 分页查询怎么实现
- python中并发编程基础1
- magic number
- 使用拦截器分析Java EE应用程序的性能下降/提高
- 某位程序猿柬埔寨开发offer到手,薪资翻倍,去吗?网友:面向阎王编程...
- mysql in 截断_MySQL十进制字段’数据在第1行的第x列被截断’问题
- html特殊文字符号
- ios GCD ---- (1)
- ERROR: libx264 not found
- Java程序性能优化技巧
- 基于AIML2.0写一个机器人
- 网上收集的一些Java应用 选择自 yukikaze 的 Blog
- 数据预处理——样本分布(正态分布、偏态分布)
- php mongodb的pecl,PECL方式安装php-mongodb扩展步骤详解
- u-boot编译构成之 MLO(2)
- Windows 11通过WSA及ADB运行安卓应用
- 【文献翻译】Evaluating five different adaptive decomposition methods for EEG signal seizure detection
- Java实验6 --模拟物流快递系统程序设计
- 论文研读 —— 7. Very Deep Convolutional Networks for Large-Scale Image Recognition (1/3)
热门文章
- 块内拉升lisp_计算机辅助设计基础试题lpar;完整版rpar;
- Android mPaaS 接入流程
- #Note#matlab中关于直角坐标、柱坐标作图问题
- 【JavaScript】-- 隐式数据类型转换
- EasyAR+微信小程序识别图片开发记录
- h5ai界面修改_解决宝塔面板使用h5ai报错的问题
- 英国约克大学留学生本科没有毕业申请硕士你还在犹豫吗
- Notification和NotificationManager的使用(一)
- win7下android开发环境搭建(win7 64位)
- 快速排序java简单实现