<一>爬虫介绍

说到互联网的原理,我们可能有着一个感受:打开浏览器,输入网址,就能看到网页,而这个过程中我们不会考虑网络如何工作,浏览器如何工作。那么如果没有浏览器,我们能不能获取到网页的内容?本章将介绍如何不通过浏览器的帮助来获取、格式化、理解数据。

这里使用的是python3

网络连接

各个网页都存储在服务器上,客户端需要使用地址向指定的服务器获取指定的网页。这里的客户端通常是浏览器,但也可以是我们的原生代码,浏览器在数据交换的过程中用的也是代码,发送get请求,获得html网页,然后渲染出好看的界面。我们的python也可以作为代码请求网络服务器获取html网页代码,即使不显示成可视化界面,我们仍可以通过各种方式处理html中包含的各种数据。
首先,我们还是来看看如何请求浏览器获得html网页里的种种数据。
1、若没有urllib库,可以x先执行下面命令安装库:

1
2
pip install urllib
#或者pip3 install urllib

2、通过python请求页面,获取页面代码

1
2
3
from urllib.request import urlopen
html=urlopen("http://pythonscraping.com/pages/page1.html")
print(html.read())

3、将该段代码保存为test.py,然后在终端运行如下命令:

1
python test.py

运行结果如下图:

这里给各位提供一个方法,在浏览器界面上右键,选择“查看源代码”就可以看到当前网页的html源代码,你也可以根据自己获取到的代码进行一个比对。我们看看浏览器上的源代码如下图:

对比以上两个内容,可以发现实际上是一样的。到此为止,我们就用三行代码获取到了html网页。

更进一层的数据处理

假如说我希望获取到html网页中的标题。原始办法实际上就是处理字符串,截取head标签的内容。这样非常复杂。我们提出BeautifulSoup库,让他来方便快捷的定位处理数据。它就好比一个认识html网页的人,可以简单快捷的定位我们要的数据。
1、安装beautifulsoup4库

1
2
3
pip install beautifulsoup4
#或者pip3 install beautifulsoup4
#实际上大多数的python库都可以直接通过pip获取。

2、使用beautifulsoup4获取前面网页中的标题h1

1
2
3
4
5
6
7
8
9
10
11
from urllib.request import urlopen
from bs4 import BeautifulSoup
html=urlopen("http://pythonscraping.com/pages/page1.html")
bsObj = BeautifulSoup(html.read()) #用BeautifulSoup构造封装html的内容
print(bsObj.h1) #获取h1标签内容
'''
以下三种调用方式都可以产生同样的结果
print(html.body.h1)
print(body.h1)
print(html.h1)
'''

构造完的bsObj就是一个有着结构化的对象。我们可以轻松获取其中任意节点的属性。
获取的结果:

1
<h1>An Interesting Title</h1>

更可靠的爬虫

网络数据往往不太友好,如果你要批量处理一些页面,但他们又会在运行中出现,比如这个网页有的标签那个网页没有,或者访问的网页404,服务器宕机等等。如果大量处理网页,实际上这些异常可能会在中间某个网页时出现,如果我们没有应对这样未知异常的处理办法,爬虫中途断了,会前功尽弃。所以我们在这里提出,要在一开始就估计可能出现的所有异常。
1、预估一下我们要面临的异常(基于本实验):

  • 404、500等网页异常在urlopen都会抛出HTTPError
  • 链接打不开或者URL写错了,urlopen会返回一个None对象
  • 如果你希望调用的节点标签会返回None对象
  • 如果你再继续调用None对象的子标签就会发送AttributeError错误。

2、对于上述估计的4个异常,我们的代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
from urllib.request import urlopen
from urllib.error import HTTPError
from bs4 import BeautifulSoup

def getTitle(url):
try:
html = urlopen(url)
except HTTPError as e:
return None
try:
bsObj=BeautifulSoup(html.read())
title=bsObj.body.h1
except AttributeError as e:
return None
return title

title=getTitle("http://www.pythonscraping.com/pages/page1.html")
if title==None:
print("Title could not be found")
else:
print(title)

本例中,我们创建了一个getTitle函数,在函数里面,我们先检查了HTTPError,然后检查我们是不是处理了空标签的子标签。所有的异常我们的处理方式都是返回None。便于我们在调用函数后进行情况的判断和处理。你可以更改以下访问地址,看看异常的处理结果。

鼓励我一下吧,我会有更多原创的!