网络数据抓取-二级页面-Python-requests爬虫

智能决策上手系列教程索引

我们继续上一篇抓取Boss直聘网站招聘列表的练习,进一步抓取每个招聘的详细信息。

网络数据抓取-Python-爬虫-Header-Boss直聘

代码回顾(中间啰嗦部分被省略):

url='https://www.zhipin.com/c101020100/h_101020100/?query=%E4%BA%BA%E5%B7%A5%E6%99%BA%E8%83%BD&page='
headers={
  'user-agent':'Mozilla/5.0'
}
page=1
hud=['职位名','薪资1','薪资2','地点','经验','学历','公司行业','融资阶段','公司人数','发布日期','发布人']
print('\t'.join(hud))

import requests
from bs4 import BeautifulSoup
for n in range(1,21):  
    html=requests.get(url+str(page),headers=headers)
    page+=1  
    soup = BeautifulSoup(html.text, 'html.parser')
    for item in soup.find_all('div','job-primary'):
      shuchu=[]
      shuchu.append(item.find('div','job-title').string) #职位名
     ...
      print('\t'.join(shuchu))

1. 分析页面

对于https://www.zhipin.com/c101020100/h_101020100/?query=人工智能&page=1这个页面,我们再次右击某个招聘的标题文字,检查Elements元素面板:

详细页面的链接

这里的a标记元素是一个可以点击的链接元素,它的href属性就是点击后将要打开的新页面地址,点击它就会打开这个招聘职位对应的详情页面,对比发现真正打开的页面只是比这个 href地址前面多了https://www.zhipin.com,就变成了类似https://www.zhipin.com/job_detail/7231c7f3bb87e0f51XZ43tm8F1A~.html的页面。

我们需要让爬虫自动的打开每个详细页面,并提取里面的有用信息,以便于我们存储到Excel表格里面进行分析。

下图是我们期望的顺序:

抓取流程

2. 获取链接

BeautifulSoup获取元素属性的方法是直接使用['属性名'],比如这里我们需要获取href属性,那么就只要找到这个a标记,然后.['href']就可以得到链接地址了。

建议你新建一个文件,然后使用下面精简过的代码进行测试(这里改为range(1,2)只读取第1页):

url='https://www.zhipin.com/c101020100/h_101020100/?query=%E4%BA%BA%E5%B7%A5%E6%99%BA%E8%83%BD&page='
headers={
  'user-agent':'Mozilla/5.0'
}
page=1
hud=['职位名','薪资1','薪资2','地点','经验','学历','公司行业','融资阶段','公司人数','发布日期','发布人']
print('\t'.join(hud))

import requests
from bs4 import BeautifulSoup
for n in range(1,2):  
    html=requests.get(url+str(page),headers=headers)
    page+=1  
    soup = BeautifulSoup(html.text, 'html.parser')
    for item in soup.find_all('div','job-primary'):
      shuchu=[]
      shuchu.append(item.find('div','job-title').string) #职位名     
      
      #读取每个职位的详细信息页面
      link=item.find('div','info-primary').find('h3').find('a')['href']
      print(link)
      #print('\t'.join(shuchu))

Python里面,如果你需要临时禁用一行代码,可以在它开头添加井号#;如果你需要临时禁用多行代码,那么需要在开始和结尾添加三个单引号'''

3. 请求详情页面并提取数据

打开任意一个详情页面比如这个页面,可以看到我们需要的职位详情内容包含在一个<div class='text'>的标记元素下面。

职位详情信息位置

这里有个难题,这个text div里面的内容很乱,包含了很多空格回车还有<br>这样的东西,用以前的.string是不行的,但用.text就能很好的解决这些问题

在Notebook里再新建一个代码文件,测试下面的代码:

import requests
from bs4 import BeautifulSoup
headers={
  'user-agent':'Mozilla/5.0'
}
def getDetails(link):
    xq_html=requests.get('https://www.zhipin.com'+link,headers=headers)
    xq_soup= BeautifulSoup(xq_html.text, 'html.parser')
    miaoshu=xq_soup.find('div','job-sec').find('div','text').text #获得标记的内部文字
    miaoshu=miaoshu.lstrip().rstrip() #去除开头和结尾的空格
    return miaoshu
xq=getDetails('/job_detail/7231c7f3bb87e0f51XZ43tm8F1A~.html')
print(xq)

这里我们使用了几个新的知识:

  • def getDetails(link), def xxx(a):这是创建了一个函数。def是define(定义)的意思。
    • 什么是函数?函数就是动作,跑可以是一个函数,打你也是一个函数,所以我们可以创建def run():也可以创建def hit(someone):这样的函数。
    • 创建的目的是为了使用。其实我们一致在使用函数,比如print('hello!')就是在使用print函数,执行输出hello这个单词的动作;同样,requests.get(...)也是在执行requests自身带有的get动作函数,上面的xq=getDetails(...)就是使用了我们自己创建的getDetails函数。
    • return miaoshu,这里是指函数最后输出的结果,类似html=requests.get(...)这样把获取到的页面数据输出给html这个对象。我们的getDetails函数也会把整理后的miaoshu文字输出给下面的xq
  • 元素.text元素.string差不多效果,都是得到元素里面的文字,但.text可以去掉掺杂在里面的尖括号。
  • lstrip().rstrip(),左右去掉多余的空格,left-strip,right-strip的意思。

4. 合并代码

我们测试好了之后,把它们合并到一起(仍然是只拉取第一页职位列表):

强烈推荐安装Anaconda,使用它自带的Jupyter Notebook来运行下面这个代码。使用天池Notebook可能导致被Boss直聘网站禁用后无法修复的问题。

url='https://www.zhipin.com/c101020100/h_101020100/?query=%E4%BA%BA%E5%B7%A5%E6%99%BA%E8%83%BD&page='
headers={
  'user-agent':'Mozilla/5.0'
}
hud=['页数','职位名','薪资1','薪资2','地点','经验','学历','公司行业','融资阶段','公司人数','发布日期','发布人','详情']
print('\t'.join(hud))

import requests
from bs4 import BeautifulSoup
import time
def getDetails(link):
    xq_html=requests.get('https://www.zhipin.com'+link,headers=headers)
    xq_soup= BeautifulSoup(xq_html.text, 'html.parser')
    miaoshu=''
    try:
        miaoshu=xq_soup.find('div','job-sec').find('div','text').text #获得标记的内部文字
        miaoshu=miaoshu.lstrip().rstrip() #去除开头和结尾的空格
    except:
        miaoshu='None'
    return miaoshu 

for n in range(1,2):  
    html=requests.get(url+str(n),headers=headers)
    soup = BeautifulSoup(html.text, 'html.parser')
    liebiao=soup.find_all('div','job-primary')
    for item in liebiao:
      shuchu=[]
      shuchu.append(str(n))
      shuchu.append(item.find('div','job-title').string) #职位名
      
      xinzi=item.find('span','red').string
      xinzi=xinzi.replace('k','')
      xinzi=xinzi.split('-')
      shuchu.append(xinzi[0]) #薪资起始数
      shuchu.append(xinzi[1]) #薪资起始数
      
      yaoqiu=item.find('p').contents
      shuchu.append(yaoqiu[0].string  if len(yaoqiu)>0 else 'None') #地点
      shuchu.append(yaoqiu[2].string  if len(yaoqiu)>2 else 'None') #经验
      shuchu.append(yaoqiu[4].string  if len(yaoqiu)>4 else 'None') #学历
      
      gongsi=item.find('div','info-company').find('p').contents
      shuchu.append(gongsi[0].string  if len(gongsi)>0 else 'None') #公司行业
      shuchu.append(gongsi[2].string  if len(gongsi)>2 else 'None') #融资阶段
      shuchu.append(gongsi[4].string if len(gongsi)>4 else 'None') #公司人数
      
      shuchu.append(item.find('div','info-publis').find('p').string.replace('发布于','')) #发布日期
      shuchu.append(item.find('div','info-publis').find('h3').contents[3].string) #发布人
      
      #读取每个职位的详细信息页面
      link=item.find('div','info-primary').find('h3').find('a')['href']
      xq=getDetails(link)
      shuchu.append(xq)      
      print('\t'.join(shuchu))
      time.sleep(1)

如果你的代码本来好好地,然后就不能正常运行,或者能运行但是详情字段都输出None,那么请做以下尝试:

  • 如果完全无反应,可以尝试在最初发送列表请求后添加一行print(html.text),输出最初得到的页面内容,查看是否正常,有没有被服务器拒绝的字样。
  • 检查这个链接地址是否能在浏览器正常打开。
  • 如果弹出下面这个画面,不用担心,手工输入一下验证码就好了,然后可以继续爬数据。这是因为Boss直聘网站服务器发觉你请求页面的频率太多了,要确认一下你是真人而不是爬虫。
  • 你可能需要多次修改for n in range(1,21)中的1,这个1代表从第几页列表开始爬取,Boss直聘似乎是每次爬取100个详情页面(3个列表页)左右就要验证一下,所以你需要3页3页的爬取,然后粘贴到excel中放到一起。
    Boss直聘网站的人工验证

目前还不确定Boss直聘的反爬虫机制,不过下一篇我们一定会深入讨论更多内容,届时也许会有更好办法。

这里在getDetails函数里面增加了try:...except:...这个用法,它表示尝试着执行try后面的代码,如果运行出错(比如找不到对应的标记元素导致find函数失败),那么就执行except:后面的代码。

5. 关于请求失败

Boss直聘的页面相对还是比较容易抓取的,但是如果你频繁发送页面请求,他们的服务器会把你的网络IP地址给封禁,让你再也请求不到他们服务器的任何数据。

如果你不确定当前电脑的IP是否被他们服务器封禁,可以在浏览器里面查看打开你代码中的任意链接,看是否能正常访问,如果可以那就没事。Boss直聘有时候封禁你只是临时的,你只要在浏览器内正常验证一下表示当前你是真人不是爬虫,那么就能解除封禁

这种封禁一般是几分钟到1小时,罕见彻底封禁不自动解禁的。

如果你被封禁了又急需解锁,那么恐怕最快的办法就是换个IP了,可以试试看换台电脑或者换到别的网线接口上,如果是家庭宽带,也可以试试看拔掉网线过几分钟再插上。

原则上讲,网站服务器一般不会采用封IP的办法的,因为如果是一个公司共用这个宽带,那么一旦封禁IP,全公司都不能访问他们的网站了,其他人会觉得这个网站很糟而弃用。

我并不确定Boss直聘网站是否真的采用了封IP的方法,无论如何,下一篇我们将讨论如何破解另外一种反爬虫的机制。——对于封禁IP的方法来反爬虫,代码上几乎是误解的,你必须有很多个IP来运行你的爬虫,很多个IP可以是很多台电脑,也可以是代理服务器,暂时我们不讨论这个。

如果你希望成为一个真正的爬虫专家,那么你需要认真的学习一些计算机网络通信的基础知识,可以在网上购买一些大学计算机通信专业的课本来看。——当然这不是我推荐每个人去做的。

6. 后续学习

经过这三篇文章的学习,你应该已经准备好迈入编程的门槛了,接下来的情况天池Notebook可能就不够用了,建议你正式下载和安装Anaconda。
请认真参照我的这个教程进行。

Anaconda安装和Jupyter Notebook上手教程


智能决策上手系列教程索引

每个人的智能决策新时代

如果您发现文章错误,请不吝留言指正;
如果您觉得有用,请点喜欢;
如果您觉得很有用,欢迎转载~


END

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,504评论 6 496
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,434评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,089评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,378评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,472评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,506评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,519评论 3 413
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,292评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,738评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,022评论 2 329
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,194评论 1 342
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,873评论 5 338
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,536评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,162评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,413评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,075评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,080评论 2 352

推荐阅读更多精彩内容

  • 用于python面试整理,主要来源于http://www.cnblogs.com/skiler/p/6952707...
    十里江城阅读 2,348评论 0 13
  • 1. 概述 本文主要介绍网络爬虫,采用的实现语言为Python,目的在于阐述网络爬虫的原理和实现,并且对目前常见的...
    Lemon_Home阅读 2,741评论 0 21
  • Python语言特性 1 Python的函数参数传递 看两个如下例子,分析运行结果: 代码一: a = 1 def...
    伊森H阅读 3,060评论 0 15
  • 爬虫文章 in 简书程序员专题: like:128-Python 爬取落网音乐 like:127-【图文详解】py...
    喜欢吃栗子阅读 21,748评论 4 412
  • 作者:京(来自豆瓣) 年前,带孩子回了趟老家给祖宗上坟。刚下过一场暌违已久的大雪,从乡村水泥路到田埂,运动鞋沾了厚...
    舰一阅读 228评论 0 0