c爬虫抓取网页数据(新手练习爬虫不过分吧?这篇爬虫实战教程,拿走不谢!)
优采云 发布时间: 2022-01-14 09:13c爬虫抓取网页数据(新手练习爬虫不过分吧?这篇爬虫实战教程,拿走不谢!)
最近暑假快到了,很多朋友都在找暑期实习吧?前几天,朋友的小弟暑假想找个实习来锻炼自己,但面对网上千篇一律的实习招聘信息,不知所措。然后我的朋友给我发了一条“请求帮助”的消息。得知大致情况后,我立即用爬虫爬取了练习网的信息,并将数据结果发送过去,分分钟解决了问题。请我吃饭会不会太过分了?
本爬虫实战教程不仅适合新手练习爬虫,也适合需要找实习资料的朋友!
希望看完这篇文章,能够清楚的知道整个爬虫流程,并且能够独立完成,二来可以通过自己的爬虫实战得到自己想要的信息。
好吧,事不宜迟,让我们开始吧!
内容主要分为两部分:
页面分析爬虫步骤详解
一、目标页面分析
首先,我们应该知道我们的爬虫目标是什么,对吧?俗话说,知己知彼,百战不殆。我们已经知道我们要爬的页面是“实习网”,所以我们首先要到实习网看看有什么数据。
实习网址:
页面如下:
比如我们要找的职位就是“品牌运营”职位的数据。因此,您可以直接在网页的搜索框中输入品牌运营。您会注意到网址已更改!
注:我们要抓取的页面是这个页面:品牌运营
在我们的爬取页面中,我们需要观察那里有哪些数据,一个页面中有几条数据。这点很重要,跟后面的代码编写有关,可以帮你检查页面上的所有信息是否都被爬取了。
此时,我们要注意的是,我们所在的页面是“一级页面”。在浏览过程中,我们随机点击一个帖子进入后,会显示“二级页面”。这时候你也会发现url又出现了。改变了。
比如我们点击一个品牌运营实践,二级页面会自动跳转到这个,生成一个新的链接。如图所示:
如何抓取页面上的信息?
在分析过程中,我们发现有的信息在一级页面,有的在二级页面。
在一级页面,我们可以得到什么信息?如图所示:
一共有五个有效数据:职位、公司名称、*敏*感*词*、薪水、地址
在二级页面中,我们来看看可以获得哪些有效数据、字段和刻度。如果觉得阶段很重要,也可以纳入爬虫的范围,但我个人认为这不影响实习。毕竟,它不是在寻找正式的工作。影响不会很大,但是招聘的实习生数量比较重要。这里没有显示新兵的数量,也无法在图片上显示。以后可以添加。
此时,我们一共需要抓取7个数据,加上“人数”,一共8个数据,就是我们爬虫最终的目标数据。
抓取“静态”网页
下面分析一下什么是静态网页,什么是动态网页。对于静态网页,随着html代码的生成,页面的内容和显示效果基本不会改变——除非你修改了页面代码。动态网页并非如此。虽然页面代码没有改变,但是显示的内容会随着时间、环境或数据库操作的结果而改变。
它们的区别在于静态网页中的数据是一劳永逸的,也就是说一次性给你。动态网页中的数据是随着页面的逐步加载而逐渐呈现出来的,也就是说,如果使用静态网页的爬虫技术,是无法获取其中所有数据的。
值得强调的是,动态网页不应与页面内容是否动态相混淆。这里所说的动态网页与网页上的各种*敏*感*词*、滚动字幕等视觉动态效果没有直接关系。动态网页也可以是纯文本内容或收录各种*敏*感*词*内容。这些只是特定于网页。内容的呈现形式,无论网页是否具有动态效果,只要是动态网站技术生成的网页,都可以称为动态网页。
点击“鼠标右键”,点击“查看网页源代码”,最终效果如图(部分截图):
这是最终反馈给您的数据。如果你发现你想要的数据都在里面,那么就可以说是静态页面,否则就认为是“动态页面”。
今天这里的案例是一个静态网页。
众所周知,在编写代码之前,我们必须知道我们使用哪些方法、库和模块来帮助您解析数据。常用的数据解析方法有:re正则表达式、xpath、beatifulsoup、pyquery等。
我们需要用到的是xpath解析方法来分析定位数据。
二、爬虫代码说明
导入相关库
爬取的第一步是考虑在爬取过程中需要哪些库。您必须知道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]
# 获取二级页面的链接
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)
需要注意的是,二级页面也是一个页面,在爬取里面的数据的时候需要请求这个页面。因此,①②③处的代码完全相同。
4、翻页操作
https://www.shixi.com/search/index?key=%E6%95%B0%E6%8D%AE%E5%88%86%E6%9E%90&page=1
https://www.shixi.com/search/index?key=%E6%95%B0%E6%8D%AE%E5%88%86%E6%9E%90&page=2
https://www.shixi.com/search/index?key=%E6%95%B0%E6%8D%AE%E5%88%86%E6%9E%90&page=3
随意复制几个不同页面的 URL 并观察差异。这里可以看出page参数后面的数字是不一样的,哪一页是数字,数字就是数字。
x = "https://www.shixi.com/search/index?key=数据分析&page="
url_list = [x + str(i) for i in range(1,61)]
由于我们已经爬取了60页的数据,所以这里构造了60个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')
这一套之后,爬虫的思路是不是瞬间清晰了?眼睛:我会的!手:我还是不会。多加练习。初学者不要急于求成,项目不多,但有技巧。看透一个比看十个要有效得多。
想要获取源码的朋友,点赞+评论,私聊~