跟蹤鏈接實現python爬蟲

爬取網頁內容首先要做的就是得到鏈接,以下是得到鏈接的代碼:

#coding=utf-8

import urllib2	# 引入需要用的模塊
import re

# 下載網頁源代碼
def download(url,user_agent = 'wswp',num_retries = 2):
    '''
    @user_agent:設置代理
    @num_retries:設置重新下載的次數
    '''
    print 'Downloading:',url
    headers = {'User-agent':user_agent}     
    request = urllib2.Request(url)
    try:     # 異常處理
        html = urllib2.urlopen(request).read()
    except urllib2.URLError as e:
        print 'Download error:',e.reason    # 輸出錯誤原因
        html = None
        if num_retries > 0:         
            if hasattr(e,'code') and 500 <= e.code < 600:
                # 當錯誤提示中包含錯誤代碼而且代碼是500~600之間的數字時,執行下列代碼
                download(url,user_agent,num_retries - 1)
    return html


# 得到html文件中的鏈接
def get_links(html):
    webpage_regex = re.compile('<a[^>]+href=["\'](.*?)["\']',re.IGNORECASE)
    return webpage_regex(html)

# 抓取鏈接
def link_crawler(seed_url,link_regex):
    crawl_queue = [seed_url]
    while crawl_queue:
        url = crawl_queue.pop()
        html = download(url)
        for link in get_links(html):	# 遍歷get_links(html)得到的列表
            if re.match(link_regex,link):	# 判斷link是否符合給定的正則表達式
                crawl_queue.append(link)
                
# 調用link_crawler函數
link_crawler('http://example.webscraping.com','/[index|view]')
以上爲完整的程序代碼。對於正則表達式的相關知識,可以看http://www.cnblogs.com/huxi/archive/2010/07/04/1771073.html,個人認爲這篇博文挺好的。

由於在一些網頁中會存在相對鏈接,上面的代碼就不中用了。可以看下面完善的代碼(需要引入urlparse模塊):

def link_crawler(seed_url,link_regex):
    crawl_queue = [seed_url]
    while crawl_queue:
        url = crawl_queue.pop()
        html = download(url)
        for link in get_links(html):
            if re.match(link_regex,link):
                link = urlparse.urljoin(link)		# 將相對url地址改爲絕對url地址
                crawl_queue.append(link)
這時,相對鏈接的問題就解決了,但是還有一個問題,那就是重複鏈接的問題。不廢話了,看下面的代碼:

def link_crawler(seed_url,link_regex):
    crawl_queue = [seed_url]
    # set函數用於輸出不帶重複內容的列表(列表中的重複內容會被刪掉)
    seen = set(crawl_queue)     # 訪問過得鏈接
    while crawl_queue:
        url = crawl_queue.pop()
        html = download(url)
        for link in get_links(html):   
            if re.match(link_regex,link):
                link = urlparse.urljoin(link)
                if link not in seen:    # 判斷此鏈接是否在已訪問鏈接列表中
                    seen.add(link)
                    crawl_queue.append(link)    
ok了,終於可以爬取網頁中所包含的所有鏈接了,而且還是逐層訪問哦。



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章