暑假来临,好多小伙伴都在找暑期实习吧?前几天,朋友弟弟,想在暑假期间找个实习工作锻炼自己,可是面对网络上几千条实习招聘信息,简直让人头大。随后朋友向我发出了“请求帮助”的信息,我了解了大致情况后,立马用爬虫爬取了实习网的的信息,将数据结果发了过去,问题分分钟解决。这请我吃一顿饭不过分吧?
这篇爬虫实战教程,不仅适合新手练习爬虫,也适合需要找实习信息的朋友!
希望在看了这篇文章后,能够清晰的知道整个爬虫流程,并且能够独立自主的完成,其次,能够通过自己的爬虫实战,获取自己想要的信息。
好了,话不多说,咱们就开始吧!
内容主要分为三大部分:
1、页面分析
2、爬虫步骤详解
一、目标页面分析
首先,我们应该要知道自己的爬虫目标是个什么东西吧?俗话说,知己知彼,百战不殆。我们已经知道自己要爬取的页面是“实习网”,所以,咱们首先得去实习网看看,都有些什么数据。
实习网址:https://www.shixi.com/search/...
页面如下:
例如我们要找的岗位是“品牌运营”岗位的数据。因此直接在网页的搜索框输入品牌运营就行了。你会发现url发生了变化!
注意:我们要爬取的页面就是这页:https://www.shixi.com/search/...品牌运营
在我们的爬取页面中,我们需要观察有哪些数据,并且一个页面中有几条数据。这个非常重要,关系到后面的代码编写,以及可以帮你检查,是否爬取到了页面的所有信息。
此时,我们要注意的是,我们所在的页面是“一级页面”,在浏览过程中,我们 点击随意一个岗位进入后呈现的是“二级页面”,此时你也会发现url又发生了变化。
例如,我们点一个品牌运营实习,二级页面就会自动跳转成这样,产生一个新的链接。如图:
要爬取页面上的那些信息呢?
我们在分析过程中发现,有些信息是在一级页面中,有些是在二级页面中。
在一级页面中,我们可以获取那些信息呢?如图所示:
总共有五条有效数据:职位、公司名、学历、薪资、地址
在二级页面中,我们来看看可以获取什么有效数据,领域和规模,阶段如果你觉得重要的话,也可以纳入爬虫范围,但是我个人认为,这并不影响实习,毕竟不是找正式工作,影响不会很大,反而是招聘实习生的数量更为重要,这里并未显示招聘人数,无法在图片上呈现,后续可加上。
到这里,我们一共需要抓取7个数据,加上“人数”一共8个数据,这也就是我们爬虫的最终目标数据。
爬取“静态”网页
这里分析下什么叫静态网页,什么叫动态网页。静态网页,随着html代码的生成,页面的内容和显示效果就基本上不会发生变化了--除非你修改页面代码。而动态网页则不然,页面代码虽然没有变,但是显示的内容却是可以随着时间、环境或者数据库操作的结果而发生改变的。
它们的区别就在于:静态网页中的数据,是一劳永逸,也就是说一次性给你。动态网页中的数据,是随着页面一步步加载出来,而逐步呈现的,也就是你用静态网页的爬虫技术,无法获取到其中所有的数据。
值得强调的是,不要将动态网页和页面内容是否有动感混为一谈。这里说的动态网页,与网页上的各种动画、滚动字幕等视觉上的动态效果没有直接关系,动态网页也可以是纯文字内容的,也可以是包含各种动画的内容,这些只是网页具体内容的表现形式,无论网页是否具有动态效果,只要是采用了动态网站技术生成的网页都可以称为动态网页。
点击 “鼠标右键”,点击 “查看网页源代码”,最终效果如图(部分截图):
这就是,最终反馈给你的数据,如果你发现自己想要的数据都在这里面,那么就可以说是静态页面,如若不然,则考虑为“动态页面”。
今天这里的案例是静态网页。
大家知道,在写代码之前要先知道,我们要用哪些方式,哪些库,哪些模块去帮你解析数据。常见用来解析数据的方法有:re正则表达式、xpath、beatifulsoup、pyquery等。
我们需要用到的是xpath解析法来分析定位数据。
二、爬虫代码讲解
1、导入相关库
爬虫的第一步是要考虑好,爬虫过程中需要用到哪些库,要知道python是一个依赖于众多库的语言,没有库的Python是不完整的。
import pandas as pd # 用于数据存储
import requests # 用于请求网页
import chardet # 用于修改编码
import re # 用于提取数据
from lxml import etree # 解析数据的库
import time # 可以粗糙模拟人为请求网页的速度
import warnings # 忽略代码运行时候的警告信息
warnings.filterwarnings("ignore")
2、请求一级页面的网页源代码
url = 'https://www.shixi.com/search/index?key=品牌运营&districts=&education=0&full_opportunity=0&stage=0&practice_days=0&nature=0&trades=&lang=zh_cn'
headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36'}
rqg = requests.get(url, headers=headers, verify=False) ①
rqg.encoding = chardet.detect(rqg.content)['encoding'] ②
html = etree.HTML(rqg.text)
这里我们要注意①②两个地方。在①处,有两个参数,一个是headers一个是verify。其中headers是一种反反扒的措施,让浏览器认为爬虫不是爬虫,而是人在用浏览器去正常请求网页。verify是忽略安全证书提示,有的网页会被认为是一个不安全的网页,会提示你,这个参数你记住就行。
在②处,我们已经获取到了网页的源码。但是由于网页源代码的编码方式和你所在电脑的解析方式,有可能不一致,返回的结果会导致乱码。此时,你就需要修改编码方式,chardet库可以帮你自动检测网页源码的编码。(一个很好用的检测文档编码的三方库chardet)
3、解析一级页面网页中的信息
# 1. 公司名
company_list = html.xpath('//div[@class="job-pannel-list"]//div[@class="job-pannel-one"]//a/text()')
company_list = [company_list[i].strip() for i in range(len(company_list)) if i % 2 != 0]
# 2. 岗位名
job_list = html.xpath('//div[@class="job-pannel-list"]//div[@class="job-pannel-one"]//a/text()')
job_list = [job_list[i].strip() for i in range(len(job_list)) if i % 2 == 0]
# 3. 地址
address_list = html.xpath('//div[@class="job-pannel-two"]//a/text()')
# 4. 学历
degree_list = html.xpath('//div[@class="job-pannel-list"]//dd[@class="job-des"]/span/text()')
# 5. 薪资
salary_list = html.xpath('//div[@class="job-pannel-two"]//div[@class="company-info-des"]/text()')
salary_list = [i.strip() for i in salary_list]
4、获取二级页面的链接
deep_url_list = html.xpath('//div[@class="job-pannel-list"]//dt/a/@href')
x = "https://www.shixi.com"
deep_url_list = [x + i for i in deep_url_list]
此时,你可以看到,我直接采用xpath一个个去解析一级页面中的数据分析。在代码末尾,可以看到:我们获取到了二级页面的链接,为我们后面爬取二级页面中的信息,做准备。
解析二级页面网页中的信息
demand_list = []
area_list = []
scale_list = []
for deep_url in deep_url_list:
rqg = requests.get(deep_url, headers=headers, verify=False) ①
rqg.encoding = chardet.detect(rqg.content)['encoding'] ②
html = etree.HTML(rqg.text) ③
# 6. 招聘人数
demand = html.xpath('//div[@class="container-fluid"]//div[@class="intros"]/span[2]/text()')
# 7. 公司领域
area = html.xpath('//div[@class="container-fluid"]//div[@class="detail-intro-title"]//p[1]/span/text()')
# 8. 公司规模
scale = html.xpath('//div[@class="container-fluid"]//div[@class="detail-intro-title"]//p[2]/span/text()')
demand_list.append(demand)
area_list.append(area)
scale_list.append(scale)
要注意的是,二级页面也是页面,在爬取其中的数据时,也需要请求页面。所以,①②③处的代码,都是一模一样的。
5、翻页操作
https://www.shixi.com/search/...
https://www.shixi.com/search/...
https://www.shixi.com/search/...
随意复制几个不同页面的url,观察它们的区别。这里可以看到,也就page参数后面的数字不同,是第几页,数字就是几。
x = "https://www.shixi.com/search/index?key=数据分析&page="
url_list = [x + str(i) for i in range(1,21)]
由于我们爬取了20页 的数据,这里就构造出了20个url,他们都存在url_list这个列表中。
我们现在来看看整个代码吧,我就不再文字叙述了,直接在代码中写好了注释。
import pandas as pd
import requests
import chardet
import re
from lxml import etree
import time
import warnings
warnings.filterwarnings("ignore")
def get_CI(url):
# 请求获取一级页面的源代码
url = 'https://www.shixi.com/search/index?key=品牌运营&districts=&education=0&full_opportunity=0&stage=0&practice_days=0&nature=0&trades=&lang=zh_cn'
headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36'}
rqg = requests.get(url, headers=headers, verify=False)
rqg.encoding = chardet.detect(rqg.content)['encoding']
html = etree.HTML(rqg.text)
# 获取一级页面中的信息:一共有5个信息。
# ①公司名
company_list = html.xpath('//div[@class="job-pannel-list"]//div[@class="job-pannel-one"]//a/text()')
company_list = [company_list[i].strip() for i in range(len(company_list)) if i % 2 != 0]
#②岗位名
job_list = html.xpath('//div[@class="job-pannel-list"]//div[@class="job-pannel-one"]//a/text()')
job_list = [job_list[i].strip() for i in range(len(job_list)) if i % 2 == 0]
#③地址
address_list = html.xpath('//div[@class="job-pannel-two"]//a/text()')
# ④ 学历
degree_list = html.xpath('//div[@class="job-pannel-list"]//dd[@class="job-des"]/span/text()')
# ⑤薪资
salary_list = html.xpath('//div[@class="job-pannel-two"]//div[@class="company-info-des"]/text()')
salary_list = [i.strip() for i in salary_list]
# ⑥获取二级页面的内容
deep_url_list = html.xpath('//div[@class="job-pannel-list"]//dt/a/@href')
x = "https://www.shixi.com"
deep_url_list = [x + i for i in deep_url_list]
demand_list = []
area_list = []
scale_list = []
# 获取二级页面中的信息:
for deep_url in deep_url_list:
rqg = requests.get(deep_url, headers=headers, verify=False)
rqg.encoding = chardet.detect(rqg.content)['encoding']
html = etree.HTML(rqg.text)
#① 需要几人
demand = html.xpath('//div[@class="container-fluid"]//div[@class="intros"]/span[2]/text()')
# ②公司领域
area = html.xpath('//div[@class="container-fluid"]//div[@class="detail-intro-title"]//p[1]/span/text()')
# ③公司规模
scale = html.xpath('//div[@class="container-fluid"]//div[@class="detail-intro-title"]//p[2]/span/text()')
demand_list.append(demand)
area_list.append(area)
scale_list.append(scale)
# ④ 将每个页面获取到的所有数据,存储到DataFrame中。
data = pd.DataFrame({'公司名':company_list,'岗位名':job_list,'地址':address_list,"学历":degree_list,
'薪资':salary_list,'岗位需求量':demand_list,'公司领域':area_list,'公司规模':scale_list})
return(data)
x = "https://www.shixi.com/search/index?key=数据分析&page="
url_list = [x + str(i) for i in range(1,61)]
res = pd.DataFrame(columns=['公司名','岗位名','地址',"学历",'薪资','岗位需求量','公司领域','公司规模'])
# 这里进行“翻页”操作
for url in url_list:
res0 = get_CI(url)
res = pd.concat([res,res0])
time.sleep(3)
# 保存数据
res.to_csv('aliang.csv',encoding='utf_8_sig')
这样一套下来,爬虫的思路是不是瞬间清晰明了?眼睛:我会了!手:我还是不会。得多加练习啊。初学者不要急于求成,项目不在多,在精。踏踏实实吃透一个远比看会十个更有效。
想要获取源代码的小火伴们,点赞+评论,私聊哦~