1. 程式人生 > >用Python寫網路爬蟲-學習總結

用Python寫網路爬蟲-學習總結

一.關於爬蟲的一些零散知識

1.Robots協議

大多數網站的主頁下會有robots.txt檔案,標識了爬蟲爬取該網站資訊時,哪些資源是有限制的,可以使用Python的標準庫robotparser來檢測將要爬取的url連結是否被允許:


# coding=utf-8
import robotparser

# 例項話一個Robots協議檢測物件
rp = robotparser.RobotFileParser()
# 設定robots協議檔案的路徑
rp.set_url("http://baike.baidu.com/robots.txt")
rp.read()

url_1 = "http://baike.baidu.com/client/12dhy40"
user_agent_1 = "Baiduspider" # 列印訪問許可權 print rp.can_fetch(user_agent_1, url_1) url_2 = "http://baike.baidu.com/item/Python" user_agent_2 = "Baiduspider" # 列印訪問許可權 print rp.can_fetch(useragent=user_agent_2, url=url_2)
列印結果:
/usr/bin/python2.7 /home/mxd/文件/WorkPlace/python/PythonStudy/test/test.py
False
True
Process finished with 
exit code 0

2.識別網站使用的技術

利用builtwith模組可以檢測出網站使用的技術資訊:

# coding=utf-8
import builtwith

# 列印網站使用技術的資訊
print builtwith.parse('http://www.imooc.com/')
列印結果:
/usr/bin/python2.7 /home/mxd/文件/WorkPlace/python/PythonStudy/test/test.py
{u'javascript-frameworks': [u'React', u'AngularJS', u'jQuery', u'Vue.js'], u'web-servers'
: [u'Nginx']} Process finished with exit code 0

3.檢視網站所有者的資訊

WHOIS協議可以查詢到域名註冊者的資訊,Python中針對該協議的模組為whois:

# coding=utf-8
import whois

# 列印網站所有者的資訊
print whois.whois('http://www.imooc.com/')
列印結果:
{u'updated_date': [datetime.datetime(2016, 2, 5, 0, 0),
datetime.datetime(2016, 2, 5, 4, 19, 20)],
u'status': [u'ok https://icann.org/epp#ok',
u'ok http://www.icann.org/epp#OK'],
u'name': u'zhang yu',
u'dnssec': u'unsigned',
u'city': u'beijingshi',
u'expiration_date': [datetime.datetime(2018, 10, 6, 0, 0),
datetime.datetime(2018, 10, 6, 2, 57, 51)],
u'zipcode': u'100120',
u'domain_name': [u'IMOOC.COM', u'imooc.com'],
u'country': u'CN',
u'whois_server': u'grs-whois.hichina.com',
u'state': u'bei jing',
u'registrar': u'HICHINA ZHICHENG TECHNOLOGY LTD.',
u'referral_url': u'http://www.net.cn',
u'address': u'beijingshi,,',
u'name_servers': [u'NS3.DNSV3.COM',
u'NS4.DNSV3.COM',
u'ns3.dnsv3.com',
u'ns4.dnsv3.com'],
u'org': u'open',
u'creation_date': [datetime.datetime(2012, 10, 6, 0, 0),
datetime.datetime(2012, 10, 6, 2, 57, 51)],
u'emails': [u'[email protected]',
u'[email protected]',
u'[email protected]']}

二.下載網頁

使用urllib2模組進行網頁的下載,在上一篇部落格中,拉取百度百科的詞條獲得詞條對應的url,但url可能已經過期,我們再去拉取會報異常,所以需要使用try-except捕獲異常:

try:
    html_doc = urllib2.urlopen(url)
except urllib2.URLError as e:
    # 異常情況,列印異常原因和狀態碼
print e.reason, e.code
使用urllib2下載網頁的時候,可能會出現異常,其中code為4xx為請求異常,5xx為伺服器錯誤,當URLError的code為5xx時,可以考慮重新發起請求:
# 下載網頁的函式#
# num_retries為遇到異常重新發起網路請求的次數,預設為2次
def downloadHtml(url, num_retries = 2):
    try:
        html_doc = urllib2.urlopen(url)
    except urllib2.URLError as e:
        html_doc = None
if num_retries > 0:
            if hasattr(e, 'code') and 500 <= e.code < 600:
                # URLError.code5xx可以重新請求
return downloadHtml(url, num_retries - 1)

    return html_doc
(2-1)ID遍歷爬蟲

很多網站由於資料挺多,會採用page切換的方式展現資料,類似於:

http://www......../page=1

http://www......../page=2

這樣的。可以使用迴圈,自動爬取每個page對應的資料。

【模組簡介-itertools】

itertools模組模組用於生成各種迴圈器。

        |-  itertools.count(start, step) : 從start開始,每隔step生成一個數字,直到無窮大

無限迴圈器   |-  itertools.cycle(seq):無限次的迴圈seq中的每一個item

                     |-  itertools.repeat(item):無限迴圈輸出item

因為我們並不知道page的最後一個數是多少,因此可以使用itertools進行無限次向後遞進迴圈:

import itertools
# itertools.count(1)可以從1開始無限次向後迴圈,1,2,3,4
for page in itertools.count(1):
    # 生成不同pageurl連結
url = "http://www.xxxxx.com/page={0}".format(page)
    html_doc = downloadHtml(url)
    if html_doc is None:
        break
    else:
        # 處理html_doc....
上面的程式碼中,當遇到某一page對應的url下載到的html_doc為None時,就認為已經到最後一頁了,即停止繼續爬取網頁,但有些情況下,html_doc可能是因為某一page對應的網頁失效,或其他原因而導致下載失敗,但其後面的page對應url的網頁正常,那麼上面的程式碼就有問題了,需要進一步改進:
import itertools
# 設定最大出錯,即html_doc為空的最大次數
max_errors = 5
num_errors = 0  # 當前出錯的次數
for page in itertools.count(1):
    # 生成不同pageurl連結
url = "http://www.xxxxx.com/page={0}".format(page)
    html_doc = downloadHtml(url)
    if html_doc is None:
        num_errors += 1
if num_errors >= max_errors:
            # 當連續5個page下載錯誤,即停止繼續爬取
break
    else:
        num_errors = 0 # 出錯次數置為0
# 處理html_doc....

(2-2)連結爬蟲

“百度百科”中爬取詞條的時候,在每個詞條網頁中會包含相關的詞條,我們可以使用爬蟲對當前網頁中其他詞條資訊進行抓取,這樣就可以爬取得到大量的詞條資訊,但是我們會發現,爬取到的詞條的url連結如下①:

① |-  /view/76320.htm  相對連結

② |-  http://baike.baidu.com/view/76320.htm  絕對連結

而完整的url如②,①為相對連結,它不包括協議和伺服器部分,②為絕對連結,對於瀏覽器來說,絕對/相對連結都可以被識別,但對於urllib2來說,只能識別絕對連結,因為要將相對連結拼接成為絕對連結,此時可以使用urlparse模組進行拼接,將相對連結url_relative拼接為絕對連結url_full:

import urlparse
# 相對連結 url_relative
# 絕對連結 url_full
# url_templet 為模板url,也是一個絕對連結
url_full = urlparse.urljoin(url_templet, url_relative)

(2-3)支援代理

有些url的訪問需要一個代理IP:

import urllib2
# 使用proxy代理訪問url
proxy = "http://www.proxyURL" # 代理的連結
opener = urllib2.build_opener()
proxy_params = {urllib2.urlparse(url).scheme: proxy}
opener.add_handler(urllib2.ProxyHandler(proxy_params))
# requesturllib2.Request()
response = opener.open(request)

由此完整的downloadHtml()函式可以寫成如下的方式:

import urllib2

def downloadHtml(url, user_agent="Mollia/5.0", proxy=None, num_retries=2):
    header = {"User-Agent": user_agent}
    # 建立一個Request物件
request = urllib2.Request(url, headers=header)
    
    opener = urllib2.build_opener()
    
    if proxy: # 如果有代理
proxy_params = {urllib2.urlparse(url).scheme: proxy}
        opener.add_handler(urllib2.ProxyHandler(proxy_params))
        
    try:
        html_doc = opener.open(request).read()
    except urllib2.URLError as e:
        html_doc = None
if num_retries > 0:
            if hasattr(e, 'code') and 500 <= e.code < 600:
                return downloadHtml(url, user_agent, proxy, num_retries - 1)
            
    return html_doc

(2-4)下載限速

有些網站訪問對訪問速度進行了限制,為了不讓爬蟲被禁止,需要對爬蟲下載網頁的速度進行一定的限制:

import urlparse
import datetime, time

class Throttle:

    def __init__(self, delay):
        self.delay = delay # 需要延遲的時間
# 字典用來儲存某個域名訪問的時間
self.domains = {}

    def wait(self, url):
        # url中獲取域名部分
domain = urlparse.urlparse(url).netloc
        # self.domains中獲取到domain對應的上次訪問的時間
# 此處使用字典的get()方法獲取,可以避免因為key不存在而引起的異常
last_accessed = self.domains.get(domain)

        if self.delay > 0 and last_accessed is not None:
            # 計算得到應該sleep的時間
sleep_seconds = self.delay - (datetime.datetime.now() - last_accessed).seconds

            if sleep_seconds > 0:
                # 進行sleep
time.sleep(sleep_seconds)

        # 更新/增加該域名domain對應的訪問時間資訊
self.domains[domain] = datetime.datetime.now()

上面的類,使用了一個字典,來儲存每個域名最近一次訪問的時間,每次訪問一個域名的url的時候,比對上次訪問時間,要是沒有超過延時delay,則進行相應時間的sleep操作,否則繼續訪問,有了上面的類,我們就可以實現下載限速的目的:
# 設定下載限速的時間
# 即一個域名每次訪問的時間間隔最小為3s
delay = 3
thrittle = Throttle(delay)
# ..... 獲取要訪問的url ......
thrittle.wait(url) # 針對url進行wait()過程
# 進行網頁下載
html_doc = downloadHtml(url, user_agent, proxy, num_retries)

相關推薦

Python網路爬蟲學習總結

一.關於爬蟲的一些零散知識 1.Robots協議 大多數網站的主頁下會有robots.txt檔案,標識了爬蟲爬取該網站資訊時,哪些資源是有限制的,可以使用Python的標準庫robotparser來檢測將要爬取的url連結是否被允許: # coding=utf-8 im

Python網路爬蟲》第一章踩坑

教程使用環境為pyhon2.x,使用python3.x進行學習時遇到一些坑,記錄下解決辦法。 由於python2.x中的urllib2模組在3.x中被整合到了urllib模組中,教程中涉及urllib2的部分的程式碼需調整 p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; f

Python 網路爬蟲 第2版

內容簡介 暢銷的 Python 網路爬蟲開發實戰圖書全新升級版,上一版年銷量近 40000 冊。 針對 Python 3.6 版本編寫。 Internet 上包含了許多有用的資料,其中大部分是可以免費公開訪問的。但是,這些資料不容易使用,它們內嵌在網站的架構和樣式中,在提取時也需要多加小心。網

Python網路爬蟲》下載

2018年11月01日 13:27:27 qq_43576443 閱讀數:5 標籤: 程式設計 資料

2018Python網路爬蟲(視訊+原始碼+資料)

課程目標 實現Python寫網路爬蟲入門 適用人群 資料零基礎愛好者,職場新人 ,在校大學生 課程簡介 1.基本Http請求以及驗證方式分析 2.Python用於處理Html格式資料beautifulsoup模組 3.Pyhton的request

python網路爬蟲-爬取新浪微博評論

新浪微博需要登入才能爬取,這裡使用m.weibo.cn這個移動端網站即可實現簡化操作,用這個訪問可以直接得到的微博id。 分析新浪微博的評論獲取方式得知,其採用動態載入。所以使用json模組解析json程式碼 單獨編寫了字元優化函式,解決微博評論中的嘈雜干擾

Python網路爬蟲系列(三)表單處理

import urllib,urllib2 LOGIN_URL = r'http://example.webscraping.com/user/login' LOGIN_EMAIL = '[email protected]' LOGIN_PASSWORD ='q

WSWP(python網路爬蟲)筆記 一:實現簡單爬蟲

wswp中的程式碼是通過python2的語法來寫的,在學習的過程中個人比較喜歡python3,因此準備將wswp的示例程式碼用python3重寫一遍,以加深映像。 開始嘗試構建爬蟲 識別網站所用技術和網站所有者 構建網站所使用的技術型別的識別和尋找

Python網路爬蟲》第一章原始碼Python3版本

作者改寫後的Python3版本原文Python2版本import re import urllib.parse import urllib.request import time from datetime import datetime import urllib.robo

網路爬蟲爬取新浪新聞----Python網路爬蟲實戰學習筆記

今天學完了網易雲課堂上Python網路爬蟲實戰的全部課程,特在此記錄一下學習的過程中遇到的問題和學習收穫。 我們要爬取的網站是新浪新聞的國內版首頁 下面依次編寫各個功能模組 1.得到某新聞頁面下的評論數 評論數的資料是個動態內容,應該是存在伺服器

人人都能Python出LSTM-RNN的程式碼![你的神經網路學習最佳起步]

0. 前言 本文翻譯自部落格: iamtrask.github.io ,這次翻譯已經獲得trask本人的同意與支援,在此特別感謝trask。本文屬於作者一邊學習一邊翻譯的作品,所以在用詞、理論方面難免會出現很多錯誤,假如您發現錯誤或者不合適的地方,可以給我留言,謝謝! -

入門級Python一個簡單的網路爬蟲下載和獲取資料

學會如何使用API通過url(Uniform Resource Locator 統一資源定位符)連線網路,獲取網站的API獲取url儲存的API,request執行獲取的urlrequests.get(url) 定義一個變數,將API響應儲存在裡面,呼叫json將r儲存的ap

Python爬蟲(1)

一、網路爬蟲與搜尋引擎的關係   爬蟲相當於眼睛和耳朵,是收集資料的。 引擎相當於大腦,是理解和處理資料的。   搜尋引擎大致可分為四個子系統:下載系統、分析系統、索引系統、查詢系統。而爬蟲只是下載系統    上圖是搜尋引擎的一

Python網絡爬蟲(高清版)PDF

頁面 逆向 網上 編程語言 線程 ajax 是什麽 保護 term 用Python寫網絡爬蟲(高清版)PDF百度網盤鏈接:https://pan.baidu.com/s/1kdRFAEuze-A9ToWVXHoCXw 提取碼:8ib1 復制這段內容後打開百度網盤手機App,

python 爬蟲 爬取得資料儲存方式

mysql: 首先配置檔案: ITEM_PIPELINES = { firstbloodpro.pipelines.MysqlproPipeline:300},配置好管道 第二配置好所需要的使用者名稱等 HOST='localhost' POST=3306 USE

Python 3網路爬蟲開發實戰+精通Python爬蟲框架Scrapy學習資料

《Python 3網路爬蟲開發實戰》介紹瞭如何利用Python 3開發網路爬蟲,首先介紹了環境配置和基礎知識,然後討論了urllib、requests、正則表示式、Beautiful Soup、XPath、pyquery、資料儲存、Ajax資料爬取等內容,接著通過多個案例介紹了不同場景下如何實現資料爬取,後介

教女朋友學python系列--手把手教你Python3進行網路爬蟲

手把手教你用Python3進行網路爬蟲 2018/6/11 星期一 整理 執行的環境: win10 x64 安裝了anaconda3,基於Python3環境執行 使用Pycharm程式設計 1. 前期工作 安裝

自己動手網路爬蟲學習筆記

剛開始學《自己動手寫網路爬蟲》,只實現了第一部分的內容。現在做一個總結。 這本書中主要用到了HttpClient和HtmlParser這兩個開源的jar包。同時,還要依賴codec.這個開源包。 HttpClient用的是3.x版本的。HtmlParser用

Python 爬蟲時應該注意哪些坑

1. 新增user-agent,header。避免一開始就被遮蔽掉。推薦用urllib2,requests(最近才用這個,發現很好用) 2. 編碼用utf-8,本地儲存的時候用codes.open 來儲存中文字元 3. lxml解析的速度要比beautifulsoup快的多 4. 如果beautiful和l

Python一個簡單的爬蟲

和朋友都灰常懶,不想上下滾動頁面看價格,所以寫了一個爬蟲,用於儲存商品價格。 環境:macOS、python3.5 IDE:pycharm 使用的庫:BeautifulSoup、urllib BeautifulSoup:優秀的HTML/XML的解析