网络爬虫

网络爬虫的基本思想

  • 通过网站域名获取HTML数据
  • 根据目标信息解析数据
  • 存储目标信息
  • 如果有必要,移动到另一个网页重复以上过程

下面是一个简单的爬虫示例,主要运用了两个库

urllibBeautifulSoup

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
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://pythonscraping.com/pages/page1.html")
if title is None:
print("Title could not be found")
else:
print(title)

在这个例子中,使用了两个try保障了这个域名不为空,且包含h1这个元素

复杂HTML解析

BeautifulSoup

举个例子:

1
2
3
4
5
6
7
8
9
10
# BeautifulSoup的.get_text()会把超链接,段落和标签都清楚掉,只剩下一串不带标签的文字
from urllib.request import urlopen
from bs4 import BeautifulSoup


html = urlopen("http://www.pythonscraping.com/pages/warandpeace.html")
bsObj = BeautifulSoup(html)
nameList = bsObj.findAll("span", {"class": "green"})
for name in nameList:
print(name.get_text())

这个例子截取的网页中有一段小说的章节,其中人物名称部分的属性为class = "green"使用bs的findall将所有带class = "green"的元素找出来,再用.get_text()将人名过滤出来。

BeautifulSoup对象

  • Beautifulsoup

    上面例子中的bsObj

  • 标签tag对象

    Beautifulsoup对象通过findall()find(),或者直接用bsObj.div.h1来获取一列对象或者一个对象

  • NavigableString

    用来表示标签的文字

  • Comment

    用来查找HTML文档的注释标签,like this <!-- 123 -->

导航树

导航树(Navigating tree)通过标签在闻到中的位置来查找标签。(感觉上就是DOM的树结构了)

处理子标签和其他后代标签(虐子)

在BeautifulSoup库中,孩子(child)和后代(descendant)有显著的不同:子标签就是一个夫标签的下一级,而后代标签是一个夫标签下面所有级别的标签。因此可以说,所有子标签都是后代标签,但不是所有的后代标签都是子标签。

一般情况下BeautifulSoup函数总是处理当前标签的后代标签。例如,bsObj.body.h1选择了body标签后代里的第一个h1标签,而不会去找body外面的标签。

于此类似,bsObj.div.findAll("img")会找出文档中第一个div标签,然后获取这个div后代里的所有img标签列表。