文章目录
前言
本次案例是爬取51job网站的职位信息升级版
第一版入门请点击查看
如有错误,还望指正,转载请注明出处。
本次爬取网址:点击此处
提示:以下是本篇文章正文内容,下面案例可供参考
一、模块使用
1.本次升级版用到的模块一共有五个
import requests as r
import bs4
import re
import openpyxl
import threading
具体的模块详细使用将在下面列出,有需要可自行了解:
re模块正则表达式
HTML标签处理模块:bs4.beautifulsoup
Python—requests模块详解
openpyxl处理excle表格详解
本文的小核心 : threading模块
二、详解
1.父页面与子页面
注意:这里的父页面是指你可以看到所有的与网络安全相关的职位,并附带简单介绍:
子页面则是你想查看职位的详细信息:
2.思路分析与代码
首先我们需要确认下目的:将该职位所有父页的子页面的详细信息爬出
1.首先需要获取到父页的源代码
2.从获取到的源码中找出子页所在的标签位置
3.将子页面url找出并形成列表
确认好思路,开始上代码:坐稳扶好,耐心观看。
1):首先我们既然要获取父页源码,就需要一个获取源码的函数,所以第一步:
代码如下(示例):
import requests as r
import bs4
import re
import openpyxl
import threading
#步骤一
h = {"User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:88.0) Gecko/20100101 Firefox/87.0"}
#url = ()
def get_html(url):
response = r.get(url,headers = h) #这里的r为requests,在调用模块时定义
response.encoding = "gbk" #编码为“国标k”
return response.text #返回源码
到这里一个获取源码模块就写好了,只要往里传一个网址就可以!
2):调用第一步函数,获取源码后进行子页url查找并形成列表
import requests as r
import bs4
import re
import openpyxl
import threading
#步骤一
h = {"User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:88.0) Gecko/20100101 Firefox/87.0"}
#url = ()
def get_html(url):
response = r.get(url,headers = h) #这里的r为requests,在调用模块时定义
response.encoding = "gbk" #编码为“国标k”
return response.text #返回源码
#步骤二
def get_urllist(jobname): #定义函数 get_urllist()
urllist = [] #一个空列表用于接收子页面url
i = 0
while i < 30: #这里进行页面的循环 i代表当前递增页面,30这个参数代表总页面
i += 1 #自增
#下面这里调用**步骤一**的函数获取到源码。该url中有两个{},为两个变量,jobname代表要搜索的工作名字,i代表页数。
urlinfo = get_html("https://search.51job.com/list/010000,000000,0000,00,9,99,{},2,{}.html".format(jobname,i))
#这里则用到了正则表达式对源码进行检索,因为该页面的源码用了模糊处理,所以比较特殊。
#其中\\代表输出一个\,"."{6,13}代表任意字符6位到13位,\d{9},代表9位数字
j = re.findall(r"https:\\/\\/jobs.51job.com\\/.{6,13}\\/\d{9}.html",urlinfo)
for q in j: #对检索出来的模糊处理源码进行去模糊
urllist.append(q.replace("\\","")) #将\\ 替换为空
#print(urllist)
return urllist #返还完美的子页面url
至此,30页的子页链接都放在urllists列表里了。我们可以进行下一步的操作了
3): 从子页html源码中筛选我们需要的信息
思路: 由于我们前两步已经获取到了各个子页的url,所以可以利用"get_html"函数返回html源码,利用浏览器审查,逐一找到需要信息的标签并筛选出来,最后找到我们需要文本信息,放到列表中返回。
代码如下(示例):
import requests as r
import bs4
import re
import openpyxl
import threading
#步骤一
h = {"User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:88.0) Gecko/20100101 Firefox/87.0"}
#url = ()
def get_html(url):
response = r.get(url,headers = h) #这里的r为requests,在调用模块时定义
response.encoding = "gbk" #编码为“国标k”
return response.text #返回源码
#步骤二
def get_urllist(jobname): #定义函数 get_urllist()
urllist = [] #一个空列表用于接收子页面url
i = 0
while i < 30: #这里进行页面的循环 i代表当前递增页面,30这个参数代表总页面
i += 1 #自增
#下面这里调用**步骤一**的函数获取到源码。该url中有两个{},为两个变量,jobname代表要搜索的工作名字,i代表页数。
urlinfo = get_html("https://search.51job.com/list/010000,000000,0000,00,9,99,{},2,{}.html".format(jobname,i))
#这里则用到了正则表达式对源码进行检索,因为该页面的源码用了模糊处理,所以比较特殊。
#其中\\代表输出一个\,"."{6,13}代表任意字符6位到13位,\d{9},代表9位数字
j = re.findall(r"https:\\/\\/jobs.51job.com\\/.{6,13}\\/\d{9}.html",urlinfo)
for q in j: #对检索出来的模糊处理源码进行去模糊
urllist.append(q.replace("\\","")) #将\\ 替换为空
#print(urllist)
return urllist #返还完美的子页面url
#步骤三
def get_html_info(html):
try: #try与except为异常捕获:执行try里的代码,如果报错,执行except
jobname = []
jobmoney = []
comname = []
jobjy = []
jobfl = []
jobneed = []
cominfo = []
soup = bs4.BeautifulSoup(html,"html.parser")
jn = soup.find("div",class_="cn")
jobname.append(jn.h1.text)
jm = soup.find("div",class_="cn")
jobmoney.append(jm.strong.text)
#print(jobname,jobmoney)
cm = soup.find("p",class_="cname")
comname.append(cm.a.text)
jj = soup.find("p",class_="msg ltype")
#print(jobjy.replace(" |"," "))
jobjy.append(jj.text.replace("\xa0\xa0|"," "))
jf = soup.findAll("span",class_=("sp4"))
j = ""
for i in jf:
j += i.text + " "
jobfl.append(j)
jneed = soup.find("div",class_="bmsg job_msg inbox")
jobneed.append(jneed.p.text)
#print(jobneed)
ci = soup.find("div",class_="tmsg inbox")
cominfo.append(ci.text)
#print(cominfo)
sum = jobname + jobmoney + comname + jobjy + jobfl + jobneed + cominfo
#print(sum)
return sum
except: #如果报错,return空值
return []
3.进行多线程执行函数并添加到Excel表
思路: 终于来到收尾的一步,这里也是我们调用整个代码执行的总步骤,可以说上面写的函数都是在这里被依次调用,本次主要利用openpyxl来进行保存,利用threading进行多线程并调用之前写的函数进行配合,废话不多说上代码。
import requests as r
import bs4
import re
import openpyxl
import threading
#步骤一
h = {"User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:88.0) Gecko/20100101 Firefox/87.0"}
#url = ()
def get_html(url):
response = r.get(url,headers = h) #这里的r为requests,在调用模块时定义
response.encoding = "gbk" #编码为“国标k”
return response.text #返回源码
#步骤二
def get_urllist(jobname): #定义函数 get_urllist()
urllist = [] #一个空列表用于接收子页面url
i = 0
while i < 30: #这里进行页面的循环 i代表当前递增页面,30这个参数代表总页面
i += 1 #自增
#下面这里调用**步骤一**的函数获取到源码。该url中有两个{},为两个变量,jobname代表要搜索的工作名字,i代表页数。
urlinfo = get_html("https://search.51job.com/list/010000,000000,0000,00,9,99,{},2,{}.html".format(jobname,i))
#这里则用到了正则表达式对源码进行检索,因为该页面的源码用了模糊处理,所以比较特殊。
#其中\\代表输出一个\,"."{6,13}代表任意字符6位到13位,\d{9},代表9位数字
j = re.findall(r"https:\\/\\/jobs.51job.com\\/.{6,13}\\/\d{9}.html",urlinfo)
for q in j: #对检索出来的模糊处理源码进行去模糊
urllist.append(q.replace("\\","")) #将\\ 替换为空
#print(urllist)
return urllist #返还完美的子页面url
#步骤三 :过滤出我们想要的信息
def get_html_info(html):
try: #try与except为异常捕获:执行try里的代码,如果报错,执行except
jobname = []
jobmoney = []
comname = []
jobjy = []
jobfl = []
jobneed = []
cominfo = []
soup = bs4.BeautifulSoup(html,"html.parser")
jn = soup.find("div",class_="cn")
jobname.append(jn.h1.text)
jm = soup.find("div",class_="cn")
jobmoney.append(jm.strong.text)
#print(jobname,jobmoney)
cm = soup.find("p",class_="cname")
comname.append(cm.a.text)
jj = soup.find("p",class_="msg ltype")
#print(jobjy.replace(" |"," "))
jobjy.append(jj.text.replace("\xa0\xa0|"," "))
jf = soup.findAll("span",class_=("sp4"))
j = ""
for i in jf:
j += i.text + " "
jobfl.append(j)
jneed = soup.find("div",class_="bmsg job_msg inbox")
jobneed.append(jneed.p.text)
#print(jobneed)
ci = soup.find("div",class_="tmsg inbox")
cominfo.append(ci.text)
#print(cominfo)
sum = jobname + jobmoney + comname + jobjy + jobfl + jobneed + cominfo
#print(sum)
return sum
except: #如果报错,return空值
return []
#步骤四 :进行多线程并保存为Excel文档
def save_info(url): #为多线程执行的函数
html = get_html(url) #获取源码
text = get_html_info(html) #筛选出源码中我们需要的信息
text.append(url) #text列表中的最后地方添加url地址
ws.append(text) #添加到ws中
if __name__ == "__main__": #总执行!
urllist = get_urllist("网络安全") #首先获取到"网络安全"工作的所有子页面url并形成列表
#print(urllist)
wb = openpyxl.Workbook() # 获取工作簿 就是一个excle层面的对象,在获取工作簿的同时已经创建了一个默认的工作表
ws = wb.active # 激活
title = ["职位","工资","公司名称","经验","福利","工作需要","公司简介"] # 先创建一个title,方便我们Excel表的查看。
ws.append(title) # 添加title
for url in urllist: # 从获取到的子页面url中逐个提取url,
t = threading.Thread(target=save_info,args=(url,)) # target后接执行函数,args后接传值 尤其注意threading里args必须是元组形式
t.start() # 开启多线程
wb.save("haha-max.xlsx") # 结束后保存为haha-max.xlsx
到此直接运行,我们就可以轻松爬取到所有的有关网络安全职位的信息了,由于使用了多线程,我在今天查询时是一共一千思百多条,爬了4分钟(快的一批,与网速有关)。
1.Excel结果展示
总结
基本每一条代码都有注释,没理解可以多看两遍。我也试了两天才搞好,所以不用气馁。
这次案例是上次案例的升级版,不得不说多线程确实nb,速度根本不是一个档次
如果你能看到这里并且爬虫成功,我对你的耐心感到敬佩。
如有错误,还望指正,如果能帮助到你,不胜荣幸。