Crawler——鏈接爬蟲

来源:http://www.cnblogs.com/llhy1178/archive/2017/05/05/6810638.html
-Advertisement-
Play Games

對數據的提取和收集也是數據分析中一大重點,所以,學習爬蟲是非常有用的。完成數據採集,對後面的數據分析做下基礎。 今天,要介紹的是來自《Web Scraping With Python》中的一個示例——鏈接爬蟲。對於此類進行了簡單的總結,便於相互學習。 ...


對數據的提取和收集也是數據分析中一大重點,所以,學習爬蟲是非常有用的。完成數據採集,對後面的數據分析做下基礎。

今天,要介紹的是來自《Web Scraping With Python》中的一個示例——鏈接爬蟲。對於此類進行了簡單的總結,便於相互學習。

#! /usr/bin/env python
# -*- coding:utf-8 -*-
import re
import urlparse
import urllib2
import time
from datetime import datetime
import robotparser
import Queue
# 鏈接爬蟲
'''
一個鏈接爬蟲需要考慮以下幾個問題:
1.下載網頁時,我們可能會遇到不可控制的錯誤,比如請求的網頁可能不存在。就要用到try和except語句,捕獲異常。
2.下載網頁時,我們也可能會遇上臨時性的錯誤,比如伺服器過載返回的503 Service Unavailable錯誤。就要多嘗試幾次下載。
3.一些網站可能會封殺預設的用戶代理,所以,我們應該重新設置一個用戶代理user_agent='wswp'。
4.下載網站鏈接時,應當考慮符合自己目標的鏈接,篩選出自己感謝的東西。通常用正則表達式來匹配這些鏈接。'<a[^>]+href=["\'](.*?)["\']'.
5.應當考慮網頁中的鏈接是什麼鏈接,如果是絕對鏈接就沒事,如果是相對鏈接就應該創建絕對鏈接。urlparse.urljoin()
6.爬取網頁的時候,經常會出現將要爬取的網頁中也有爬取過的鏈接,這樣會造成不斷迴圈。所以要建立一個URL管理器,管理爬取過的和未爬取的
7.所有爬蟲都應當遵守爬蟲協議(robots.txt),所以要引入robotparser模塊,以避免下載禁止爬取的URL
8.有時我們需要使用代理訪問某個網站。
9.如果我們爬取網站的速度過快,就會面臨被封禁或者伺服器過載的風險。所以應當在兩次下載之間添加延時。delay
10.有些網站中含有動態內容,如果爬取該網頁就會出現無限制的網頁,所以為了避免爬蟲陷阱,最好設置一個爬取深度(max_depth)——記錄到達當前網頁經過了多少鏈接。
'''
def link_crawler(seed_url, link_regex=None, delay=5, max_depth=-1, max_urls=-1, headers=None, user_agent='wswp', proxy=None, num_retries=1):
    """Crawl from the given seed URL following links matched by link_regex
    """
    # the queue of URL's that still need to be crawled
    crawl_queue = Queue.deque([seed_url])
    # the URL's that have been seen and at what depth
    seen = {seed_url: 0}
    # track how many URL's have been downloaded
    num_urls = 0
    rp = get_robots(seed_url)
    throttle = Throttle(delay)
    headers = headers or {}
    if user_agent:
        headers['User-agent'] = user_agent

    while crawl_queue:
        url = crawl_queue.pop()
        # check url passes robots.txt restrictions
        if rp.can_fetch(user_agent, url):
            throttle.wait(url)
            html = download(url, headers, proxy=proxy, num_retries=num_retries)
            links = []

            depth = seen[url]
            if depth != max_depth:
                # can still crawl further
                if link_regex:
                    # filter for links matching our regular expression
                    for link in get_links(html):
                        if re.match(link_regex, link):
                            links.extend(link)
                    # links.extend(link for link in get_links(html) if re.match(link_regex, link))

                for link in links:
                    link = normalize(seed_url, link)
                    # check whether already crawled this link
                    if link not in seen:
                        seen[link] = depth + 1
                        # check link is within same domain
                        if same_domain(seed_url, link):
                            # success! add this new link to queue
                            crawl_queue.append(link)

            # check whether have reached downloaded maximum
            num_urls += 1
            if num_urls == max_urls:
                break
        else:
            print 'Blocked by robots.txt:', url


class Throttle:
    """Throttle downloading by sleeping between requests to same domain
    """
    def __init__(self, delay):
        # amount of delay between downloads for each domain
        self.delay = delay
        # timestamp of when a domain was last accessed
        self.domains = {}

    def wait(self, url):
        domain = urlparse.urlparse(url).netloc
        last_accessed = self.domains.get(domain)

        if self.delay > 0 and last_accessed is not None:
            sleep_secs = self.delay - (datetime.now() - last_accessed).seconds
            if sleep_secs > 0:
                time.sleep(sleep_secs)
        self.domains[domain] = datetime.now()


def download(url, headers, proxy, num_retries, data=None):
    print 'Downloading:', url
    request = urllib2.Request(url, data, headers)
    opener = urllib2.build_opener()
    if proxy:
        proxy_params = {urlparse.urlparse(url).scheme: proxy}
        opener.add_handler(urllib2.ProxyHandler(proxy_params))
    try:
        response = opener.open(request)
        html = response.read()
        code = response.code
    except urllib2.URLError as e:
        print 'Download error:', e.reason
        html = ''
        if hasattr(e, 'code'):
            code = e.code
            if num_retries > 0 and 500 <= code < 600:
                # retry 5XX HTTP errors
                return download(url, headers, proxy, num_retries-1, data)
        else:
            code = None
    return html


def normalize(seed_url, link):
    """Normalize this URL by removing hash and adding domain
    """
    link, _ = urlparse.urldefrag(link) # remove hash to avoid duplicates
    return urlparse.urljoin(seed_url, link)


def same_domain(url1, url2):
    """Return True if both URL's belong to same domain
    """
    return urlparse.urlparse(url1).netloc == urlparse.urlparse(url2).netloc


def get_robots(url):
    """Initialize robots parser for this domain
    """
    rp = robotparser.RobotFileParser()
    rp.set_url(urlparse.urljoin(url, '/robots.txt'))
    rp.read()
    return rp


def get_links(html):
    """Return a list of links from html
    """
    # a regular expression to extract all links from the webpage
    webpage_regex = re.compile('<a[^>]+href=["\'](.*?)["\']', re.IGNORECASE)
    # list of all links from the webpage
    return webpage_regex.findall(html)


if __name__ == '__main__':
    link_crawler('http://example.webscraping.com', '/(index|view)', delay=0, num_retries=1, user_agent='BadCrawler')
    link_crawler('http://example.webscraping.com', '/(index|view)', delay=0, num_retries=1, max_depth=-1, user_agent='GoodCrawler')

  


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 重放攻擊 重放攻擊是指黑客通過抓包的方式,得到客戶端的請求數據及請求連接,重覆的向伺服器發送請求的行為。 比如你有一個 “購買” 的操作,當你點擊購買按鈕時,向伺服器發送購買的請求。而這時黑客對你的請求進行了抓包,得到了你的傳輸數據。 因為你填寫的都是真實有效的數據,是可以購買成功的,因此他不用做任 ...
  • .NET Core 2.0預覽版及.NET Standard 2.0 Preview 這個月也就要發佈了。 具體相關信息可以查看之前的文章 ".NET Core 2.0及.NET Standard 2.0" 。 今天來實際體驗.NET Core 2.0,正式版發佈還需要一段時間。 .NET Core ...
  • 詳情見:cookie與session的區別與聯繫 ...
  • csrf攻擊,即cross site request forgery跨站(功能變數名稱)請求偽造,這裡的forgery就是偽造的意思。網上有很多關於csrf的介紹,比如一位前輩的文章淺談CSRF攻擊方式,參考這篇文章簡單解釋下:csrf 攻擊能夠實現依賴於這樣一個簡單的事實:我們在用瀏覽器瀏覽網頁時通常會打 ...
  • 那些網上說的JDK什麼的的問題,我求你們不要誤人子弟好嗎? 出現在這個的原因就是ADT也就是你的SDK manager 的Tools版本跟你的SDK版本不相容,如果你的是SDK 23.0.2那你的Tools 時版本也要是這個,如果你實在不會,那就把所有的Tools全部下載下來就可以的 ...
  • 本文為博主辛苦總結,希望自己以後返回來看的時候理解更深刻,也希望可以起到幫助初學者的作用. 轉載請註明 出自 : "luogg的博客園" 謝謝配合! 當資料庫欄位和實體bean中屬性不一致時 之前資料庫Person名字欄位是name,PersonBean中屬性也是name,但是之後資料庫中修改為了u ...
  • 不多bb了直接上。 工具:myeclipse 2016,mysql 5.7 目的:java操作資料庫增刪改查商品信息 test資料庫的goods表 gid主鍵,自增 1、實體類Goods:封裝資料庫數據(與資料庫表中各欄位相匹配的類) 2、實現類GoodsDao(不帶DBHelper):操作資料庫實 ...
  • 定義節點: 細節說明,PNode 就代表struct Node* ,上面的表單是也可以寫成如下形式,含義是一樣的 演算法操作 1. 創建鏈表 2. 顯示鏈表數據 3. 運行測試 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...