Python进行网页内容的爬取,首先需要将网页内容下载到本地,再针对特定网页内容的结构进行网页内容的解析,获得需要的数据。
(1).网页下载
Python常用的网页下载的库有,urllib2(标准库)和Requests(第三方库),下面主要使用urllib2进行网页的下载:
【方法一】
import urllib2【方法二】
url = "https://www.baidu.com/"
print "方法一"
response = urllib2.urlopen(url)
print response.getcode(), len(response.read()) # getcode()获得请求的状态码
有些网页的访问需要传入特殊的参数,或网站本身对访问者有一定的限制:
print "方法二"【方法三】
request = urllib2.Request(url)
request.add_header('user-agent', 'Mozilla/5.0') # 伪装成浏览器访问网站
response = urllib2.urlopen(request)
print response.getcode(), len(response.read())
有些网站的访问需要特殊场景的处理器:
e.g. HTTPCookieProcessor(网站的Cookie),ProxyHandler(网站访问需要的代理),HttpsHandler(网站需要Https加密),HttpRedirectHandler(网页链接之间的跳转有自身url限制)
print '方法三'
import cookielib
# 创建一个Cookie容器
cj = cookielib.CookieJar()
# 创建一个场景处理器
handler = urllib2.HTTPCookieProcessor(cj)
# 创建opener
opener = urllib2.build_opener(handler)
# 为urllib2安装opener
urllib2.install_opener(opener)
response = urllib2.urlopen(url)
print response.getcode(), len(response.read())
print cj # 打印Cookie的内容
【说明一】
有些网站做了一些特殊处理,禁止爬虫爬取网站信息,此时我们可以通过调用request的add_header(key, value)方法,将爬虫伪装成正常的浏览器访问,我们通过查看访问百度首页的request的头信息:
可以看到request的头信息中包含很多内容,需要伪装爬虫,就需要设置User-Agent这一项:
# coding=utf-8上面除了设置User-Agent这个头信息,还设置了Origin这个头信息,有些网站为防止第三方网站的链接访问,会检查Origin这一项是否内本网站链接,基于此,有时候还需要为request的头信息中设置这一项,表示当前的访问是从Origin导过来的。
import urllib2
url = 'http://blog.csdn.net/tianmaxingkong_/article/details/52934658'
request = urllib2.Request(url)
request.add_header('user-agent', 'Mozilla/5.0') # 设置User-Agent
request.add_header('Origin', 'http://www.baidu.com') # 设置跳转网页的链接
response = urllib2.urlopen(request)
【注意】当我们的爬虫访问网站而被Forbidden的时候,往往是由于网站本身通过对访问信息的比对,禁止了爬虫的访问,此时我们可以通过浏览器正常访问,并查看浏览器访问时所携带的header和body的信息,从而在爬虫中添加这些信息就可以了。
【说明二】
爬虫在访问网站的时候,有可能需要以post的方式携带一些数据:(账号信息)
# coding=utf-8
import urllib2
url = 'http://xxxx.login.php'
request = urllib2.Request(url)
postData = urllib2.parse.urlencode([
('account', '155555@qq.com'),
('password', '1234567890'),
('loginTime', '2016-10-24 12:31:21 1249')
])
request.add_header('User-Agent', 'Mozilla/5.0')
request.add_header('Origin', 'http://xxxx/firstPage.php')
# post方式携带
response = urllib2.urlopen(request, data=postData.encode('utf-8'))
print response.getcode()
(2).网页内容解析
Python常用的网页解析有:
-| 正则表达式,
-| html.parser 网页解析器
-| BeautifulSoup(第三方库,可以使用html.parser或lxml解析器进行解析)
-| lxml 第三方网页解析器
下面使用BeautifulSoup进行网页解析。
BeautifulSoup开发者文档:
https://www.crummy.com/software/BeautifulSoup/bs4/doc/
中文文档:
https://www.crummy.com/software/BeautifulSoup/bs3/documentation.zh.html
BeautifulSoup的安装:
#方法一
pip install beautifulsoup4
#方法二
sudo apt-get install python-bs4
展示使用BeautifulSoup第三方库进行网页内容解析:
($)首先是下载网页的内容,使用urllib2进行网页内容的下载,并将网页内容装载到html_doc中,以便之后去解析。
# coding=utf-8
import urllib2
# 将要爬去的网页链接
root_url = 'http://baike.baidu.com/view/21087.htm'
# 下载网页内容
response = urllib2.urlopen(root_url)
html_code = response.getcode() # 网页状态码
html_doc = response.read() # 网页的内容
print html_code, html_doc
BeautifulSoup模块是将html页面内容构建成一个DOM树的对象,通过find_all(name, attrs, string)方法和find(name, attrs, string)来进行DOM树节点的搜索,
*| find_all(name, attrs, string) 查找DOM树中所有符合条件的节点;
*| find(name, sttrs, string) 查找DOM树中首个符合条件的节点;
【参数说明】name: 标签的名称; attrs:标签的属性和属性值;string:标签的文字。
($)爬取网页中所有<a>标签节点
# html_doc是通过urllib2模块下载“百度百科”的网页内容打印结果:
from bs4 import BeautifulSoup
# 创建一个bs4对象,html.parser为解析器,from_encoding指定了解析的编码格式
soup = BeautifulSoup(html_doc, 'html.parser', from_encoding='utf8')
# 通过DOM树树对象,得到所有标签<a>节点
links = soup.find_all('a');
for link in links:
# 分别打印每一个节点的名称,节点href的属性值,节点的文字信息
try:
name = link.name # 获取标签的名称的方法
link_href = link['href'] # 获取标签的某一属性的属性值的方法,href属性值
text = link.get_text() # 获取标签文字信息的方法
print name, link_href, text
except:
print 'fall'
a /view/2561555.htm 计算机程序设计语言【说明】通过调用BeautifulSoup对象的find_all('a')方法,获取到DOM树中所有<a>标签节点,因为网页中<a>标签有各种作用,所以上面的打印结果有好多种情况,但是有一种<a>标签的href的属性值为 /view/数字.htm 的,是该网页中包含的其他词条的链接。
a /view/2975166.htm Guido van Rossum
a /view/20965.htm *软件
a /subview/60376/5122159.htm 源代码
a /view/592974.htm 解释器
a /view/130692.htm GPL
a /view/36272.htm GNU
fall
a /view/2993364.htm 胶水语言
a /subview/10075/6770152.htm C
a /view/824.htm C++
a /view/330120.htm 应用程序
a /view/10598.htm MATLAB
fall
fall
#............此处省略多个打印结果.................
a javascript:; 编辑
a #ref_[1]_21087
($)爬取网页中包含的词条节点
【说明】查看原网页的信息可以发现,网页中词条节点的特点为,都是<a>标签,href属性的值类似于 /view/数字.htm 的格式,根据这样的特点,可以:
# html_doc是通过urllib2模块下载“百度百科”的网页内容打印结果:
from bs4 import BeautifulSoup
# 创建一个bs4对象,html.parser为解析器,from_encoding指定了解析的编码格式
soup = BeautifulSoup(html_doc, 'html.parser', from_encoding='utf8')
# 通过正则表达式来进行匹配
import re
pattern = re.compile('/view/\d*\.htm')
links = soup.find_all('a', href=pattern)
print len(links)
for link in links:
link_name = link.name # 获取标签名称的方法
link_href = link['href'] # 获取标签某一属性的属性值的方法
link_text = link.get_text() # 获取标签的文字内容的方法
print link_name, link_href, link_text
/usr/bin/python2.7 /home/mxd/文档/WorkPlace/python/PythonStudy/test.py
114
a /view/10812319.htm 锁定
a /view/2561555.htm 计算机程序设计语言
a /view/2975166.htm Guido van Rossum
a /view/20965.htm *软件
a /view/592974.htm 解释器
a /view/130692.htm GPL
a /view/36272.htm GNU
a /view/2993364.htm 胶水语言
# ...............................................此处省略很多行打印结果......................................
a /view/845405.htm Unix shell
a /view/4373007.htm TIOBE
a /view/1020193.htm 卡耐基梅隆大学
a /view/159864.htm 接口
a /view/1343775.htm OpenCV
a /view/330120.htm 应用程序
a /view/10598.htm MATLAB
a /view/119481.htm 界面设计
Process finished with exit code 0
($)抓取网页中某一词条的节点
# html_doc是通过urllib2模块下载“百度百科”的网页内容打印结果:
from bs4 import BeautifulSoup
# 创建一个bs4对象,html.parser为解析器,from_encoding指定了解析的编码格式
soup = BeautifulSoup(html_doc, 'html.parser', from_encoding='utf8')
# 抓取 href='/view/330120.htm'的节点
link_node = soup.find('a', href='/view/330120.htm')
name_link = link_node.name # 获取节点名称的方法
href_link = link_node['href'] # 获取节点某一属性的属性值的方法
text_link = link_node.get_text() # 获取节点文字内容的方法
print name_link, href_link, text_link
/usr/bin/python2.7 /home/mxd/文档/WorkPlace/python/PythonStudy/test.py
a /view/330120.htm 应用程序
Process finished with exit code 0
($)爬取网页中包含class属性的节点
【说明】查看网页的内容,会发现如下的节点,包含class这样的属性,因为class为Python的关键字,因此在抓取的时候,需要指定class属性的时候,使用class_,以便于Python的关键字区分:
from bs4 import BeautifulSoup打印结果:
# 创建一个bs4对象,html.parser为解析器,from_encoding指定了解析的编码格式
soup = BeautifulSoup(html_doc, 'html.parser', from_encoding='utf8')
# 要抓取的节点 <a class="logo cmn-inline-block" title="到百科首页" href="/">
link_node = soup.find('a', class_='logo cmn-inline-block')
node_title = link_node['title']
print node_title
/usr/bin/python2.7 /home/mxd/文档/WorkPlace/python/PythonStudy/test.py
到百科首页
Process finished with exit code 0