python网络爬虫-数据采集之遍历单个爬虫

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/wanght89/article/details/78019070

     之所以称之为爬虫(Web Carwler)是因为它们可以沿着网络爬行。它们的本质就是一种递归方式。为了找到URL链接,它们必须首先获取网页内容,检查这个页面的内容,在寻找另外一个URL,然后后获取URL对应的网页内容,不断循环这一过程。不过要注意的是:你可以这样重复采集网页,但不意味着你一直都应该这么做。当你需要的所有数据都在一个页面上时,前面例子中的爬虫就足以解决问题了。使用网络爬虫的时候,你必须非常谨慎地考虑需要消耗多少网络流量,还要经历思考能不能让采集目标服务器负载更低一些。

      在本篇博文中,我们将创建一个项目来实现“维基百科六度分隔理论”的查找方法。也就是说,我们要实现从埃里克.艾德尔的词条页面(https://en.wikipedia.org/wiki/Eric_Idle)开始,经过最少的链接点击找到凯文.贝肯的词条界面(https://en.wikipedia.org/wiki/Kevin_Bacon)。

     你应该已经知道如何写一段获取维基百科网站任何页面并提取页面链接的Python代码了:

from urllib.request import urlopen
from bs4 import BeautifulSoup
html=urlopen("https://en.wikipedia.org/wiki/Eric_Idle")
bsObj=BeautifulSoup(html,"html.parser")
for link in bsObj.findAll("a"):
      if 'href' in link.attrs:
          print(link.attrs['href'])
     你会发现结果为一系列的链接,其中有些是我们需要的,有些不是我们需要的。其实维基百科的每个页面都充满了侧边栏、页眉、页脚链接,以及连接到分类页面、对话页面和其他不包含词条的页面的链接。经过对采集页面的分析,发现那些指向词条页面(不是指向其他内容页面)的链接,会发现他们有三个特点:

     1.它们都在id是bodyContent的div标签里

     2.URL链接不包含分号

     3.URL链接都已/wiki/开头

      因此我们可以稍微调整代码来获取词条链接

from urllib.request import urlopen
from bs4 import BeautifulSoup
import re
html=urlopen("https://en.wikipedia.org/wiki/Eric_Idle")
bsObj=BeautifulSoup(html,"html.parser")
for link in bsObj.find("div",{"id":"bodyContent"}).findAll("a",href=re.compile("^(/wiki/)((?!:).)*$")):
      if 'href' in link.attrs:
          print(link.attrs['href'])
    执行后,就会看到维基百科上埃里克.艾德尔词条里所有指向其他词条的链接

    当然,写程序来找出这个静态的维基百科词条里所有的词条链接很有趣,不过没有什么实际用处。我们需要让这段程序更像下面的形式:

    1.一个函数getLinks,可以用维基百科词条/wiki/<词条名称>形式的URL链接作为参数,然后以同样的形式返回一个列表,里面包含所有的词条URL链接。

    2. 一个主函数,以某个起始词条为参数调用getLinks,再从返回的URL列表里随机选择一个词条链接,再调用getLinks,直到我们主动停止,或者在新的界面上没有词条链接了,程序才停止执行。

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("https://en.wikipedia.org"+articleUrl)
    bsObj=BeautifulSoup(html,"html.parser")
    return bsObj.find("div",{"id":"bodyContent"}).findAll("a",href=re.compile("^(/wiki/)((?!:).)*$"))

links=getLinks("/wiki/Kevin_Bacon")

while len(links)>0:
    newArticle=links[random.randint(0,len(links)-1)].attrs["href"]
    print(newArticle)
    links=getLinks(newArticle)
    执行结果如下图所示:


如果不手动停止,程序会一直运行到页面上没有词条链接为止。导入需要的Python库后,程序首先做的是用系统的当前时间生成一个随机数生成器。这样可以保证在每次程序运行的时候,维基百科词条的选择都是一个全新的随机路径。

     然后我们定义了getLinks函数,其参数是维基百科词条页面中的/wiki/<词条名称>形式的URL链接,前面加上维基百科的域名,http://en.wikipedia.org,再用域名中的网页获取一个BeautifulSoup对象。之后用前面介绍过的惨呼抽取一列词条链接所在的标签a并返回它们。

     程序的主程序首先把起始页面:https://en.wikipedia.org/wiki/Kevin_Bacon里的词条链接列表(links变量)设置成链接列表。然后用一个循环,从页面中随机找一个词条链接标签并抽取href属性,打印这个页面链接,再把这个链接传入getLinks函数,重新获取新的链接列表。当然,这里只是简单地构建一个从一个页面到另外一个页面的爬虫,要解决“维基百科六度分隔理论”问题还有一点工作要做。我们还应该存储URL链接数据并分析数据。后续会有博文继续介绍。同时在本博文中,程序的编写时需要注意一样处理的问题,参考前面的构建稳定链接的内容修改程序,增加异常处理的部分。

展开阅读全文

没有更多推荐了,返回首页