最新消息:XAMPP默认安装之后是很不安全的,我们只需要点击左方菜单的 "安全"选项,按照向导操作即可完成安全设置。

Python编程之数据爬虫抓取 下篇

XAMPP案例 admin 295浏览 0评论
永远做对的事,然后再把事做对。段永平
0Python

14. 收集链接

今天我们要准备完成我们的网络爬虫了!

首先我们需要从找到种子页上的所有链接开始,但不是像第二单元那样直接打印出来,而是需要将它们存储在一个列表中,这样你就可以利用它们继续前进。通过该列表中的所有链接来继续我们的抓取,只要有更多的页面可以抓取,就可以继续前进。

第一步定义一个过程get_all_links,它将一个代表网页上文字的字符串作为输入,并产生一个包含该网页上所有链接标签目标的URL的列表作为输出。

 

15. 获取所有链接

下面是第二单元的代码回顾:

def print_all_links(page):
    while True:
          url, endpos = get_next_target(page)
          if url:
                print url
                page = page[endpos:]
          else:
                break

我们定义了一个过程,get_next_target,它将接收一个页面,搜索该页面上的第一个链接,并将其作为url的值返回,同时还返回引用末尾的位置,这样我们就知道在哪里继续。

然后,我们定义了一个过程,print_all_links,只要页面上有更多的链接,它就会一直进行下去。它将反复找到下一个目标,打印出来,并将页面推进到结束位置以上。

我们要做的是改变这种情况,不是每次找到一个URL就打印出来,而是要收集这些URL,这样我们就可以用它们来继续抓取并找到新的页面。要做到这一点,我们将创建一个我们找到的所有链接的列表。我们将print_all_links过程改为get_all_links,这样我们就可以使用输出,这将是一个链接列表,它将对应于我们最初打印出来的链接。

 

16. 链接

包含了三个链接标签,分别指向关于爬取、行走和飞行的页面(你可以通过点击浏览器中测试页面上的链接来检查它们)。

下面是get_all_links的操作方法。

 

links = get_all_links(get_page(‘http://www.link1.com/cs101x/index.html’)

print links [‘http://www.link1.com/cs101x/crawling.html’,

‘http://www.link1.com/cs101x/walking.html’, ‘http://www.link1.com/cs101x/flying.html’]

 

因为结果是一个列表,我们可以用它来继续抓取页面。你可以自己思考如何定义get_all_links,但如果你被卡住了,可以使用下面的测验来逐步完成我们需要做的改变。

== 测验:开始get_all_links

链接的初始值应该是多少?请记住,get_all_links 的目标是返回一个页面上所有链接的列表。你将使用 link 变量来引用一个包含所有我们找到的链接的列表。

def get_all_links(page):
    links = []
    while True:
          url, endpos = get_next_target(page)
          if url:
             print url (strikthrough)
             page = page[endpos:]
          else:
                break

17. 完成网络爬虫

此时,我们已经准备好完成网络爬虫的工作了。网络爬虫的目的是能够在种子页上找到链接,将它们做成一个列表,然后按照这些链接到新的页面,那里可能会有更多的链接,你希望你的网络爬虫能够跟踪这些链接。

为了做到这一点,网络爬虫需要跟踪所有的页面。使用变量tocrawl作为剩下要抓取的页面列表。使用变量crawled来存储抓取的页面列表。

 

18. 爬取过程–第一次尝试这里是对抓取过程的描述。我们称之为伪代码,因为它比英文更精确,结构有点像Python代码,但不是实际的Python代码。当我们开发更复杂的算法时,在尝试编写Python代码来实现它们之前,用伪代码来描述它们是很有用的。(在这种情况下,这样做也是为了给你一个自己编写Python代码的机会!)从 tocrawl = [seed] crawled = []开始,而tocrawl有更多的页面:从 tocrawl中选取一个页面,将该页面添加到crawled中,将该页面上的所有链接目标添加到tocrawl中。return crawled

  • 抓取网页 Crawl Web

要启动crawl_web过程,需要提供tocrawl和crawl的初始值:

def crawl_web(seed):
    tocrawl = [seed] - initialize this variable
    crawl = []       - initialize this variable
  • 抓取网络循环the Web Loop

下一步是写一个循环来进行抓取,只要有页面可以抓取,你就会继续前进。要做到这一点,你将使用一个 while 循环,以 tocrawl 作为测试条件。你可以使用 len(tocraw) == 0 来测试列表是否为空。还有一种更简单的方法,就是只用tocrawl来写。一个空列表(一个没有元素的列表)被解释为false,而每一个非空列表被解释为true。

在循环里面,我们需要选择一个页面来抓取。对于这个测验,你的目标是找出一个好的方法来完成这个任务。有很多方法可以做到这一点,但利用我们在本单元学到的东西,你可以用一行代码来实现,它既可以将页面初始化为我们要抓取的下一个页面,也可以将该页面从tocrawl列表中删除。

最好的方法是使用pop。pop是我们见过的唯一一个真正从列表中删除元素,并且还具有返回该元素的属性的东西。如果我们使用tocrawl.pop(),就会得到tocrawl列表中的最后一个元素,将该元素从列表tocrawl中删除,并将其赋值给变量page。

def crawl_web(seed):
    tocrawl = [seed]
    crawled = []
    while tocrawl:
        page = tocrawl.pop()

因为我们首先得到的是最后一个元素,所以我们实现的是所谓的深度优先搜索depth-first-search。这意味着当我们抓取网页时,我们将查看网页链中每个页面的第一个链接,直到我们到达终点。只有这样,我们才会开始查看第一页的第二个链接以及后续的每一页。如果我们的目标是快速获得一个好的网络语料库,那么做深度优先搜索可能不是最好的方式。如果我们完成搜索,无论按照什么顺序,我们都会找到同一组网页。如果我们不能够完成搜索,而对于真正的网络爬虫来说,有太多的网页要等到我们把它们全部抓取后才能返回结果,那么我们查看网页的顺序就很重要了。

  • 抓取 If

下一步是管理链接中的循环问题。我们不想抓取已经抓取过的页面,所以我们需要的是测试页面是否被抓取的方法。

为了做出这样的决定,我们使用if。我们需要一个if的测试条件,只有在页面没有被抓取过的情况下,才会做我们抓取页面的事情。

我们应该只抓取还没有抓取的页面。crawled变量会跟踪我们已经抓取的页面。所以,我们要测试这个页面是否没有在抓取中。如果它的页面不在crawled中,那么我们就抓取。如果是,那么我们继续前进。在这个迭代中,我们在while循环中不做其他事情,继续检查下一个页面。

def crawl_web(seed):
    tocrawl = [seed]
    crawled = []
    while tocrawl:
          page = tocrawl.pop()
          if page not in crawled: 
          ...
  • 完成抓取网页

现在你已经准备好完成我们的爬虫的编写了。写两行代码来更新tocrawl的值,以反映页面上发现的所有新链接,并更新crawled的值,以跟踪已被抓取的页面。

首先,我们需要将我们在一个页面上找到的所有链接添加到页面上,我们可以使用本单元前面一个测验中的联合过程来完成。使用append,我们可以跟踪我们已经抓取的页面。

def crawl_web(seed):
    tocrawl = [seed]
    crawled = []
    while tocrawl:
          page = tocrawl.pop()
          if page not in crawled:
              union (tocrawl, get_all_links(get_page(page)))
              crawled.append(page) 
    return crawled

转载请注明:XAMPP中文组官网 » Python编程之数据爬虫抓取 下篇

您必须 登录 才能发表评论!