python爬虫之遍历单个域名
即使你没听说过“维基百科六度分隔理论”,也很可能听过“凯文 "_blank" href="https://en.wikipedia.org/wiki/Eric_Idle" rel="external nofollow" >https://en.wikipedia.org/wiki/Eric_Idle)开始,经过最少的链接点击次 数找到凯文 "_blank" href="https://en.wikipedia.org/wiki/Kevin_Bacon" rel="external nofollow" rel="external nofollow" >https://en.wikipedia.org/wiki/Kevin_Bacon)。
这么做对维基百科的服务器负载有多大影响?
根据维基媒体基金会(维基百科所属的组织)的统计,该网站每秒 会收到大约2500次点击,其中超过 99% 的点击都指向维基百科域 名[详情请见“维基媒体统计图”(Wikimedia in Figures)里的“流量 数据”(Traffic Volume)部分内容]。因为网站流量很大,所以你 的网络爬虫不可能对维基百科的服务器负载产生显著影响。不过, 如果你频繁地运行本书的代码示例,或者自己创建项目来抓取维基 百科的词条,那么希望你能够向维基媒体基金会提供一点捐赠—— 不只是为了抵消你占用的服务器资源,也是为了其他人能够利用维 基百科这个教育资源。
还需要注意的是,如果你准备利用维基百科的数据做一个大型项 目,应该确认该数据是不能够通过维基百科 API 获取的。维基百科 网站经常被用于演示爬虫,因为它的 HTML 结构简单并且相对稳定。但是它的 API 往往会使得数据获取更加高效。 你应该已经知道如何写一段 Python 代码,来获取维基百科网站的任何 页面并提取该页面中的链接了。
from urllib.request import urlopen from bs4 import BeautifulSoup html = urlopen('http://en.wikipedia.org/wiki/Kevin_Bacon') bs = BeautifulSoup(html, 'html.parser') for link in bs.find_all('a'): if 'href' in link.attrs: print(link.attrs['href'])
如果你观察生成的一列链接,会看到你想要的所有词条链接都在里 面:“Apollo 13”“Philadelphia”“Primetime Emmy Award”,等等。但是, 也有一些你不需要的链接:
//wikimediafoundation.org/wiki/Privacy_policy
//en.wikipedia.org/wiki/Wikipedia:Contact_us
其实,维基百科的每个页面都充满了侧边栏、页眉和页脚链接,以及连 接到分类页面、对话页面和其他不包含词条的页面的链接:
/wiki/Category:Articles_with_unsourced_statements_from_April_2014 /wiki/Talk:Kevin_Bacon
最近我有个朋友在做一个类似的维基百科抓取项目,他说,为了判断一 个维基百科内链是否链接到一个词条页面,他写了一个很大的过滤函 数,代码超过了 100 行。不幸的是,他没有提前花很多时间去寻找“词 条链接”和“其他链接”之间的模式,也可能他后来发现了。如果你仔细 观察那些指向词条页面(不是指向其他内部页面)的链接,会发现它们 都有 3 个共同点:
- 它们都在 id 是 bodyContent 的 div 标签里
- URL 不包含冒号
- URL 都以 /wiki/ 开头
我们可以利用这些规则稍微调整一下代码来仅获取词条链接,使用的正则表达式为 ^(/wiki/)(("):
from urllib.request import urlopen from bs4 import BeautifulSoup import re html = urlopen('http://en.wikipedia.org/wiki/Kevin_Bacon') bs = BeautifulSoup(html, 'html.parser') for link in bs.find('div', {'id':'bodyContent'}).find_all( 'a', href=re.compile('^(/wiki/)(("htmlcode">from urllib.request import urlopen from bs4 import BeautifulSoup import datetime import random import re random.seed(datetime.datetime.now()) def getLinks(articleUrl): html = urlopen('http://en.wikipedia.org{}'.format(articleUrl)) bs = BeautifulSoup(html, 'html.parser') return bs.find('div', {'id':'bodyContent'}).find_all('a', href=re.compile('^(/wiki/)(("_blank" href="https://en.wikipedia.org/wiki/Kevin_Bacon" rel="external nofollow" rel="external nofollow" >https://en.wikipedia.org/wiki/Kevin_Bacon 里的词条链接列表设置成链接标签列表(links 变量)。然后用一个循 环,从页面中随机找一个词条链接标签并抽取 href 属性,打印这个页 面,再把这个链接传入 getLinks 函数,重新获取新的链接列表。
当然,这里只是简单地构建一个从一个页面到另一个页面的爬虫,要解 决“维基百科六度分隔理论”问题还需要再做一点儿工作。我们还应该存储 URL 链接数据并分析数据。
以上就是关于python爬虫之遍历单个域名的全部知识点,感谢大家的学习和对的支持。
下一篇:详解Python中的format格式化函数的使用方法