在上一篇文章中对Python有了一定的基础学习后,我们现在要开始对网页进行爬取啦。
这次我们要爬取的网站是中国移动集团的运维案例文章和评论内容。这篇文章中将会涉及到GET请求和POST请求,以及BeautifulSoup的使用。
扩展模块的安装要让python可以对网页发起请求,那就需要用到requests之类的包。我们可以用命令行来下载安装,打开cmd,直接输入命令就会自动下载安装,非常的方便。
pip install requests
既然用到了pip,那就顺便解释一下这个东东。
pip 是 Python 著名的包管理工具,在 Python 开发中必不可少。一般来说当你安装完python后,pip也会自动安装完毕,可以直接享用,十分鲜美。
附上一些常用的pip命令
# 查看pip信息pip –version#升级pippip install -U pip# 查看已经安装的包pip list# 安装包Pip install PackageName# 卸载已经安装好的包Pip uninstall PackageName
以上这四个命令非常的实用,我在做这个爬虫期间有多次使用到。
在安装完requests包后,还需要再安装一个神器BeautifulSoup,配合lxml库,这是最近非常流行的两个库,这个是用来解析网页的,并提供定位内容的便捷接口,API非常人性化,支持CSS选择器、Python标准库中的HTML解析器,也支持 lxml 的 XML解析器
语法使用类似于XPath。通过官方的文档的阅读,很容易上手。
安装方式:
BeautifulSoup的安装
pip install beautifulsoup4
lxml的安装
pip install lxml
不报错即为安装成功
BeautifulSoup官方文档传送门
安装完上面三个包后,就开始制作我们的第一个小爬虫吧我们先来分析一下我们这次要爬取数据的网站数据。可以使用chrome浏览器自带的工具来抓包,按F12,选择Network,就可以看到所有的请求内容了。当然也可以用Fiddler这个优秀的工具来抓包,还能对请求进行截获并修改参数,大家有时间的话可以去玩一玩。这儿因为方便,我就采用了chrome浏览器自带的来进行分析了。
根据这个请求,我们能看出这个是一个GET请求。我们将headers里的内容绑定到类的属性里,接着绑定一个请求的地址。
import requests #导入requests 模块from bs4 import BeautifulSoup #导入BeautifulSoup 模块# 爬取文章案例编号和当前周期有效阅读数class BeautifulGetCaseSN():
def __init__(self): #类的初始化操作
#头部信息
self.headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.221 Safari/537.36 SE 2.X metaSr 1.0', 'Accept':'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,**;q=0.8', 'Accept-Language':'zh-CN,zh;q=0.8', 'Connection':'keep-alive', 'cookie':'JSESSIonID=48A82C60BE65ED14C5978297C03AF776; PHPSESSID=ST-10-QybrBt31XVfPBqKAT2jr''
}
#要访问的网页地址
self.web_url = 'http://net.chinamobile.com/cmccnkms-case/web/casesPortal/loadComments.action'
def get_data(self):
print('开始文章评论内容POST请求')
print('具体评论获取n')
for x in range(1,10):
#post请求的数据
web_data = {
'sort':'desc',
'pageNum':x,
'caseId':75058
}
r = requests.post(self.web_url,data=web_data, headers=self.headers)这里增加一个for循环就是为了模拟请求的页码,根据pageNum的不同,对该网址进行多次请求获取不同页面信息。
通过分析评论页的HTML数据,我发现每个评论都用包含,于是我们可以用find_all来获取全部的这个class,因为每页都有五个评论,所以可以用for循环来进行分析并输出。
下面是完整的请求代码
def get_data(self):
print('开始文章评论内容POST请求')
print('具体评论获取n')
get_name = []
get_next_name = [] for x in range(1,10):
web_data = { 'sort':'desc', 'pageNum':x, 'caseId':75058
}
r = requests.post(self.web_url,data=web_data, headers=self.headers)
all_a = BeautifulSoup(r.text, 'lxml').find_all('div','month')
print('第',x,'页')
#将上页获取的评论记录并清空当前页
get_name = get_next_name
get_next_name = [] for a in enumerate(all_a):
str_name = a[1].text.split(':') #对获取的文本内容做切割
get_next_name.append(str_name[0]) #将名字加入到当前获取记录中
if get_name == get_next_name:
print('完成') break
else: for a in get_next_name:
print(a)这里说一下我定义的两个list:get_name和get_next_name。之所以定义这两个是因为每篇文章的评论数量我是不知道的,所以我不能直接控制需要爬取的页数,只能尽可能大的写一个数。但是当页数小于我设定的页码值后会发生如下的数据重复显示事件。
于是我加入了这两个参数,来存放前一页的获取的数据,如果单页获取的数据与前一页获取的数据相同,那说明就是到了评论的最后一页,直接跳出循环,结束该篇文章的评论爬取。
好了,把这两个类实例化一下,然后开始run起来吧。
getCaseSN = BeautifulGetCaseSN() #创建类的实例,根据caseId爬取文章基础信息getData = BeautifulGetData() #创建类的实例,根据caseId爬取文章评论信息getCaseSN.get_data() getData.get_data()
成功获取到了我希望得到的目标数据,完美!
后记但是,只对一篇固定文章的爬取,远远不是我的最终目的,我的目的是,导入一份需要爬取的表格,然后进行自动的爬取,并将获取的数据输出并保存下来。在下一篇文章中,我就来讲一讲,Excel文件的导入读取与文件的导出保存。
作者:杳杳靈鳯
链接:https://www.jianshu.com/p/74f0b0edc94c



