标题无意冒犯,就是觉得这个广告挺好玩的
上面这张思维导图喜欢就拿走,反正我也学不了这么多
前言
第十五天讲了Xpath,是真的好用啊。
于是我就去亲自练习了一下,抓取“2021腾讯校招网”数据,并进行整理。
这篇属于一套新系列,挂在“偷偷学Python”系列下,写完之后会整理出来。
名字想好了,就叫“爬虫百战穿山甲”。
第一篇在这里:我要偷偷的学Python,然后惊呆所有人(第十四篇)
这是第二篇。
插播一条推送:(如果是小白的话,可以看一下下面这一段)
欢迎来到我们的圈子
我建了一个Python学习答疑群,有兴趣的朋友可以了解一下:这是个什么群
群里已经有一千八百多个小伙伴了哦!!!
(严格控制群人数,所以今年年底之前不会满群)
直通群的传送门:传送门
本系列文默认各位有一定的C或C++基础,因为我是学了点C++的皮毛之后入手的Python,这里也要感谢齐锋学长送来的支持。
本系列文默认各位会百度。
我要的不多,点个关注就好啦
然后呢,本系列的目录嘛,说实话我个人比较倾向于那两本 Primer Plus,所以就跟着它们的目录结构吧。
本系列也会着重培养各位的自主动手能力,毕竟我不可能把所有知识点都给你讲到,所以自己解决需求的能力就尤为重要,所以我在文中埋得坑请不要把它们看成坑,那是我留给你们的锻炼机会,请各显神通,自行解决。
爬虫百战穿山甲(二):Xpath爬取2021年腾讯校招网
需求分析
目标网站
https://join.qq.com/post.php?pid=1
点进去看,我们继续下一步。
页面分析
先看页面左侧,有四个标签,姑且叫它们“大标题”,用于开辟Excel工作区。
再看页面中上部分,有不少的小标签:
这些小标签下属有三种不同的情况:下拉框、文本框、暂无岗位:
Xpath分析
先看一下左边标签的Xpath,这个没有什么很难的问题,但是对于我这种小白来说还是有点难的。
/html/body/div[2]/div[2]/div[1]/ul[1]/li[1]/a
这个是绝对路径啊,也可以用相对路径,//div[2]/div[2]/div[1]/ul[1]/li[1]/a
那要怎么去一次性全提取出来嘞?
/html/body/div[2]/div[2]/div[1]/ul[1]//li//a//@href
/html/body/div[2]/div[2]/div[1]/ul[1]//li//a//text()
这一步跨出去就好办了,跨不过去的话建议先回“第十五天”再看看。
上边那些小模块的Xpath我就不说了啊,一个套路啦。
讲一下那些个下拉框吧,这个下拉框有这么几种情况:
1、这是有下拉框的:/html/body/div[2]/div[2]/div[2]/div[2]/div[1]/div[2]/div/ul/a[1]
2、这是没有下拉框但是有内容的:/html/body/div[2]/div[2]/div[2]/div[2]/div[1]/div[2]/div/span
剩下那个我也没去看。
我是这样做的:去抓所有的框,有网址的就是有下拉框,没网址的就是没下拉框。什么都没有的就是空的,空的不管它。
放码过来
同样的,实现了基本功能,并没有最终完善和重构,先结项,太忙。
不过这个项目我很喜欢,后面会绕回来再完善一遍。
不多说,思路
from openpyxl import Workbook
import requests
import re
from lxml import etree
#获取网址中的element对象
def get_data(url,headers):
response = requests.get(url, headers)
data = response.content
#print("data\n"+data)
#删除源代码中的注释
data = data.decode().replace("", "")
#print(data)
# 创建element对象
tree = etree.HTML(data)
#print("tree\n"+tree)
return tree
def parser_href_data(url_base,Tree,Xpath):
el_list = Tree.xpath(Xpath)
el_list_keep = []
for i in el_list:
el_list_keep.append(url_base + str(i))
return el_list_keep
def run():
wb = Workbook() # 打开一个excel文件
url_base = "https://join.qq.com/" # 通用网址头
headers = { # 伪装请求头
# 高端浏览器 有注释
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36"
}
# 首先访问主页
tree = get_data("https://join.qq.com/post.php?pid=1",headers)
el_list1 = parser_href_data(url_base,tree,"/html/body/div[2]/div[2]/div[1]/ul[1]//@href")
el_list2 = parser_href_data('',tree,"/html/body/div[2]/div[2]/div[1]/ul[1]//li/a/text()")
# for i in el_list1:
# print(i)
# for j in el_list2:
# print(j)
#进入每个大标签
for x,y in zip(el_list1,el_list2):
y = y.replace('/','&') #这里要再次赋值,并非原地修改
ws = wb.create_sheet(y) #这里不接受'/'
tree = get_data(x,headers)
el_list3 = parser_href_data(url_base, tree, "/html/body/div[2]/div[2]/div[2]/div[1]/ul//a/@href")
el_list4 = parser_href_data('', tree, "/html/body/div[2]/div[2]/div[2]/div[1]/ul//a//text()")
#进入每个小标签
for i,j in zip(el_list3,el_list4):
write_to_sheet = [] #这个应该放这里
write_to_sheet.append(j)
# print(j+":"+i)
# print("\n")
tree = get_data(i,headers)
#找找看有没有下拉框
el_list5 = parser_href_data(url_base, tree, "/html/body/div[2]/div[2]/div[2]/div[2]/div[1]/div[2]/div/ul//a/@href")
#如果没有下拉框
if el_list5 == []: #从列表来区分,字符串区分不了,==‘’不行,isspace也不行
#直接抓数据
#print("None")
#抓取岗位名称
el_list6 = parser_href_data('',tree,"/html/body/div[2]/div[2]/div[2]/div[2]/div[1]/div[2]/div/span//text()")
#清除空岗位
if el_list6 != []:
# print(el_list6)
#抓取岗位介绍
write_to_sheet.append(el_list6[0])
el_list7 = parser_href_data('',tree,"/html/body/div[2]/div[2]/div[2]/div[2]/div[2]/div[2]//text()")
ss = ''
for s in el_list7:
s.replace('\r\n',' ')
#print(s)
ss=ss+s+'\n'
write_to_sheet.append(ss)
#抓取岗位需求
el_list8 = parser_href_data('', tree,"/html/body/div[2]/div[2]/div[2]/div[2]/div[3]/div[2]//text()")
ss = ''
for s in el_list8:
s.replace('\r\n',' ')
# print(s)
ss = ss + s + '\n'
write_to_sheet.append(ss)
#抓取工作地点
el_list9 = parser_href_data('', tree,"/html/body/div[2]/div[2]/div[2]/div[2]/div[4]/div[2]//text()")
ss = ''
for s in el_list9:
#不正则一下还真以为我怕了它
pat = re.compile(r'[\u4e00-\u9fa5]+')
result = pat.findall(s)
for s in result:
ss = ss + s + '、'
write_to_sheet.append(ss)
#抓取招聘城市
el_list10 = parser_href_data('', tree,"/html/body/div[2]/div[2]/div[2]/div[2]/div[5]/div[2]//text()")
for s in el_list10:
s.strip()
write_to_sheet.append(s)
ws.append(write_to_sheet)
else:
el_list6 = parser_href_data('', tree,"/html/body/div[2]/div[2]/div[2]/div[2]/div[1]/div[2]/div/ul//a//text()")
for a,b in zip(el_list5,el_list6):
pass #再往下走一层抓数据
# if a.isspace():
# print("None")
# else:
# print(j + ":" + i)
# print("hellohello\n\n")
wb.save("2021腾讯校招岗位.xlsx")
wb.close()
run()
往后的部分就交给各位啦。
我做这些的过程中,发现重复度有点高,如果要封装成类进行重构的话可以考虑一下“模板方法模式”,不要生搬硬套到函数里面。
本文分享 CSDN - 看,未来。
如有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。