本节我们在对数据采集有一定了解的基础上,进行维基百科上简单的数据采集。介绍采集一个页面,采集一个网站,采集多个网站数据。读者可以在本节实验中进行实践。
网络爬虫本质上就是一种递归方式。为了找到URL链接,必须先获取网页内容,检查这个网页的内容,再寻找另一个URL,然后获取URL对应的网页内容,不断循环这一过程。
遍历单个域名
维基百科六度分隔理论
把两个不相干的主题(维基百科里用词条之间的连接,凯文贝肯的六度分隔是用出现在同一部电影中的演员来连接)用一个总数不超过六条的主题连接起来(包括原来的两个主题)。比如,埃里克埃德尔和布兰登弗雷泽都出现在电影《骑警杜德雷》里,布兰登弗雷泽和凯文贝肯都出现在电影《我呼吸的空气》里。因此根据这两个条件,埃里克埃德尔到凯文贝肯的链条主题长度只有3。
我们要做一个深度查找链接,通过一个词条链接跳到另一个上面,再循环做这件事情,完成一个随机深度链接的过程(解决六度分隔问题会在后续章节提到)。
- 一个函数getLinks,可以从维基百科词条/wiki/<词条名称>形式的URL链接作为参数,然后以同样的形式返回一个列表,里面包含所有的词条URL链接。
- 一个主函数,以某个其实词条为参数条用getLinks,再从返回的URL列表里随机选择一个词条链接,再调用getLinks,直到我们主动停止,或者在新的页面上没有词条链接了,程序才停止运行。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21from urllib.request import urlopen
from bs4 import BeautifulSoup
import re
import datetime
import random
def getLinks(articleUrl):
html = urlopen("https://en.wikipedia.org"+articleUrl)
bsObj = BeautifulSoup(html)
return bsObj.find("div",{"id":"bodyContent"}).findAll("a",href=re.compile("^(/wiki/)((?!:).)*$"))
if __name__ == '__main__':
random.seed(datetime.datetime.now()) #用当前系统时间生成一个随机数生成器。这样保证在每次运行的时候,维基百科词条的选择都是一个全新的随即路径。
links=getLinks("/wiki/Kevin_Bacon") #把起始页面里的词条链接列表设置成链接链表。
#再用一个循环
while len(links)>0:
#从页面中随机找一个词条链接抽取href,获取新的页面链接。
newArticle=links[random.randint(0,len(links)-1)].attrs["href"]
print(newArticle)
#传入新的页面链接获取新一个链接列表。
links = getLinks(newArticle)