1. 程式人生 > >Python 網路爬蟲 009 (程式設計) 通過正則表示式來獲取一個網頁中的所有的URL連結,並下載這些URL連結的原始碼

Python 網路爬蟲 009 (程式設計) 通過正則表示式來獲取一個網頁中的所有的URL連結,並下載這些URL連結的原始碼

通過 正則表示式 來獲取一個網頁中的所有的 URL連結,並下載這些 URL連結 的原始碼

使用的系統:Windows 10 64位
Python 語言版本:Python 2.7.10 V
使用的程式設計 Python 的整合開發環境:PyCharm 2016 04
我使用的 urllib 的版本:urllib2

注意: 我沒這裡使用的是 Python2 ,而不是Python3

一 . 前言

通過之前兩節(爬取一個網頁 的網路爬蟲解決爬取到的網頁顯示時亂碼問題),我們終於完成了最終的 download() 函式。
並且上上一節 ,我們通過網站地圖解析裡面的URL的方式爬取了目標站點的所有網頁。在

上一節,介紹一種方法來爬取一個網頁裡面所有的連結網頁。這一節,我們通過正則表示式來獲取一個網頁中的所有的URL連結,並下載這些URL連結的原始碼。

二 . 簡介

到目前為止,我們已經利用目標網站的結構特點實現了兩個簡單爬蟲。只要這兩個技術可用,就應當使用其進行爬取,因為這兩個方法最小化了需要下載的網頁數量。不過,對於一些網站,我們需要讓爬蟲表現得更像普通使用者:跟蹤連結,訪問感興趣的內容。

通過跟蹤所有連結的方式,我們可以很容易地下載整個網站的頁面。但是這種方法會下載大量我們並不需要的網頁。例如,我們想要從一個線上論壇中爬取使用者賬號詳情頁,那麼此時我們只需要下載賬戶頁,而不需要下載 討論輪貼的頁面。本篇部落格中的連結爬蟲將使用正則表示式來確定需要下載那些頁面。

三 . 初級程式碼

import re

def link_crawler(seed_url, link_regex):
    """Crawl from the given seed URL following links matched by link_regex
    """
    crawl_queue = [seed_url]
    while crawl_queue:
        url = crawl_queue.pop()
        html = download(url)
        # filter for links matching our regular expression
for link in get_links(html): if re.match(link_regex, link): crawl_queue.append(link) 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)

四 . 講解初級程式碼

1 .

def link_crawler(seed_url, link_regex):

這個函式就是我們要在外部使用的函式。功能:先下載 seed_url 網頁的原始碼,然後提取出裡面所有的連結URL,接著對所有匹配到的連結URL與link_regex 進行匹配,如果連結URL裡面有link_regex內容,就將這個連結URL放入到佇列中,下一次 執行 while crawl_queue: 就對這個 連結URL 進行同樣的操作。反反覆覆,直到 crawl_queue 佇列為空,才退出函式。

2 .

get_links(html) 函式的功能:用來獲取 html 網頁中所有的連結URL

3 .

webpage_regex = re.compile('<a[^>]+href=["\']'(.*?)["\']', re.IGNORECASE)

做了一個匹配模板,存在 webpage_regex 物件裡面 。匹配<a href="xxx"> 這樣的字串,並提取出裡面xxx的內容,這個xxx就是網址 URL

4 .

return webpage_regex.findall(html)

使用 webpage_regex 這個模板對 html 網頁原始碼匹配所有符合<a href="xxx"> 格式的字串,並提取出裡面的 xxx 內容。

五 . 執行

先啟動Python 終端互動指令,在PyCharm軟體的Terminal視窗中 或者 在Windows 系統的DOS視窗中執行下面的命令:

C:\Python27\python.exe -i 1-4-4-regular_expression.py

執行link_crawler() 函式:

>>> link_crawler('http://example.webscraping.com', '/(index|view)')

輸出:

Downloading:  http://example.webscraping.com
Downloading:  /index/1
Traceback (most recent call last):
  File "1-4-4-regular_expression.py", line 50, in <module>
    link_crawler('http://example.webscraping.com', '/(index|view)')
  File "1-4-4-regular_expression.py", line 36, in link_crawler
    html = download(url)
  File "1-4-4-regular_expression.py", line 13, in download
    html = urllib2.urlopen(request).read()
  File "C:\Python27\lib\urllib2.py", line 154, in urlopen
    return opener.open(url, data, timeout)
  File "C:\Python27\lib\urllib2.py", line 423, in open
    protocol = req.get_type()
  File "C:\Python27\lib\urllib2.py", line 285, in get_type
    raise ValueError, "unknown url type: %s" % self.__original
ValueError: unknown url type: /index/1

執行的時候,出現了錯誤。這個錯誤出在:下載 /index/1 URL時。這個 /index/1 是目標站點中的一個相對連結,就是完整網頁URL 的路徑部分,而沒有協議和伺服器部分。我們使用download() 函式是沒有辦法下載的。在瀏覽器裡瀏覽網頁,相對連結是可以正常工作的,但是在使用 urllib2 下載網頁時,因為無法知道上下文,所以無法下載成功。

七 . 改進程式碼

所以為了讓urllib2 能夠定為網頁,我們需要將相對連結轉換為絕對連結,這樣方可解決問題。
Python 裡面有可以實現這個功能的模組:urlparse

下面對 link_crawler() 函式進行改進:

import urlparse
def link_crawler(seed_url, link_regex):
    """Crawl from the given seed URL following links matched by 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(seed_url, link)
                crawl_queue.append(link)

八 . 執行:

執行程式:

>>> link_crawler('http://example.webscraping.com', '/(index|view)')

輸出:

Downloading:  http://example.webscraping.com
Downloading:  http://example.webscraping.com/index/1
Downloading:  http://example.webscraping.com/index/2
Downloading:  http://example.webscraping.com/index/3
Downloading:  http://example.webscraping.com/index/4
Downloading:  http://example.webscraping.com/index/5
Downloading:  http://example.webscraping.com/index/6
Downloading:  http://example.webscraping.com/index/7
Downloading:  http://example.webscraping.com/index/8
Downloading:  http://example.webscraping.com/index/9
Downloading:  http://example.webscraping.com/index/10
Downloading:  http://example.webscraping.com/index/11
Downloading:  http://example.webscraping.com/index/12
Downloading:  http://example.webscraping.com/index/13
Downloading:  http://example.webscraping.com/index/14
Downloading:  http://example.webscraping.com/index/15
Downloading:  http://example.webscraping.com/index/16
Downloading:  http://example.webscraping.com/index/17
Downloading:  http://example.webscraping.com/index/18
Downloading:  http://example.webscraping.com/index/19
Downloading:  http://example.webscraping.com/index/20
Downloading:  http://example.webscraping.com/index/21
Downloading:  http://example.webscraping.com/index/22
Downloading:  http://example.webscraping.com/index/23
Downloading:  http://example.webscraping.com/index/24
Downloading:  http://example.webscraping.com/index/25
Downloading:  http://example.webscraping.com/index/24
Downloading:  http://example.webscraping.com/index/25
Downloading:  http://example.webscraping.com/index/24
Downloading:  http://example.webscraping.com/index/25
Downloading:  http://example.webscraping.com/index/24

通過執行得到的結果,你可以看出來:雖然,現在可以下載網頁沒有出錯,但是同樣的網頁會被不斷的下載到。為什麼會這樣?這是因為這些連結URL相互之間存在連結。如果兩個網頁之間相互都有對方的連結,那麼對著這個程式,它會不斷死迴圈下去。

所以,我們還需要繼續改程序序:避免爬取相同的連結,所以我們需要記錄哪些連結已經被爬取過,如果已經被爬取過了,就不在爬取它。

九 . 繼續改進 link_crawler()函式:

def link_crawler(seed_url, link_regex):
    crawl_queue = [seed_url]
    # keep track which URL's have seen before
    seen = set(crawl_queue)
    while crawl_queue:
        url = crawl_queue.pop()
        html = download(url)
        for link in get_links(html):
            # check if link matches expected regex
            if re.match(link_regex, link):
                # form absolute link
                link = urlparse.urljoin(seed_url, link)
                # check if have already seen this link
                if link not in seen:
                    seen.add(link)
                    crawl_queue.append(link)

十 . 執行:

>>> link_crawler('http://example.webscraping.com', '/(index|view)')

輸出:

Downloading:  http://example.webscraping.com
Downloading:  http://example.webscraping.com/index/1
Downloading:  http://example.webscraping.com/index/2
Downloading:  http://example.webscraping.com/index/3
Downloading:  http://example.webscraping.com/index/4
Downloading:  http://example.webscraping.com/index/5
Downloading:  http://example.webscraping.com/index/6
Downloading:  http://example.webscraping.com/index/7
Downloading:  http://example.webscraping.com/index/8
Downloading:  http://example.webscraping.com/index/9
Downloading:  http://example.webscraping.com/index/10
Downloading:  http://example.webscraping.com/index/11
Downloading:  http://example.webscraping.com/index/12
Downloading:  http://example.webscraping.com/index/13
Downloading:  http://example.webscraping.com/index/14
Downloading:  http://example.webscraping.com/index/15
Downloading:  http://example.webscraping.com/index/16
Downloading:  http://example.webscraping.com/index/17
Downloading:  http://example.webscraping.com/index/18
Downloading:  http://example.webscraping.com/index/19
Downloading:  http://example.webscraping.com/index/20
Downloading:  http://example.webscraping.com/index/21
Downloading:  http://example.webscraping.com/index/22
Downloading:  http://example.webscraping.com/index/23
Downloading:  http://example.webscraping.com/index/24
Downloading:  http://example.webscraping.com/index/25
Downloading:  http://example.webscraping.com/view/Zimbabwe-252
Downloading:  http://example.webscraping.com/view/Zambia-251
Downloading:  http://example.webscraping.com/view/Yemen-250
Downloading:  http://example.webscraping.com/view/Western-Sahara-249

現在這個程式就是一個非常完美的程式,它會爬取所有地點,並且能夠如期停止。最終,完美得到了一個可用的爬蟲。

總結:
這樣,我們就已經介紹了3種爬取一個站點或者一個網頁裡面所有的連結URL的原始碼。這些只是初步的程式,接下來,我們還可能會遇到這樣的問題:
1 . 如果一些網站設定了 禁止爬取的URL,我們為了執行這個站點的規則,就要按照它的 robots.txt 檔案來設計爬取程式。
2 . 在國內是上不了google的,那麼如果我們想要使用代理的方式上谷歌,就需要給我們的爬蟲程式設定代理。
3 . 如果我們的爬蟲程式爬取網站的速度太快,可能就會被目標站點的伺服器封殺,所以我們需要限制下載速度。
4 . 有一些網頁裡面有類似日曆的東西,這個東西里面的每一個日期都是一個URL連結,我們有不會去爬取這種沒有意義的東西。日期是無止境的,所以對於我們的爬蟲程式來說,這就是一個爬蟲陷阱,我們需要避免陷入爬蟲陷阱。

我們需要解決上這4個問題。才能得到最終版本的爬蟲程式。

相關推薦

Python 網路爬蟲 009 (程式設計) 通過表示式獲取一個網頁的所有的URL連結下載這些URL連結原始碼

通過 正則表示式 來獲取一個網頁中的所有的 URL連結,並下載這些 URL連結 的原始碼 使用的系統:Windows 10 64位 Python 語言版本:Python 2.7.10 V 使用的程式設計 Python 的整合開發環境:PyCharm 201

python網路爬蟲例項:Requests+表示式爬取貓眼電影TOP100榜

一、前言 最近在看崔慶才先生編寫的《Python3網路爬蟲開發實戰》這本書,學習了requests庫和正則表示式,爬取貓眼電影top100榜單是這本書的第一個例項,主要目的是要掌握requests庫和正則表示式在實際案例中的使用。 二、開發環境 執行平

Python表示式一次替換文章所有特殊符號如“-,$()#+&*”之類

一個簡單的正則表示式,可能會起大作用。比如說字符集就是這樣。一篇文章如果有各種亂碼,就可以用這種方法去除。如去除“-,$()#+&*”之類符號是很方便的。按照查詢、分割、替換的套路再做一做這樣的練習。今天晚了,後續還要操作檔案來完善這一點。 import re

python—【爬蟲】學習_2(表示式篇)_2(practice)

習題來源:hackerrank  Matching Anything But a Newline(.的用法) answer :     regex_pattern = r"^(.{3}\.){3}.{3}$" Matching Digits &am

python—【爬蟲】學習_2(表示式篇)1.基礎知識

一、簡介 正則表示式本身是一種小型的、高度專業化的程式語言,而在python中,通過內嵌整合re模組,程式媛們可以直接呼叫來實現正則匹配。正則表示式模式被編譯成一系列的位元組碼,然後由用C編寫的匹配引擎執行。 r標識代表後面是正則的語句 二、正則表示式中常用的字元含義 1、普通字元和

python—【爬蟲】學習_2(表示式篇)3.re模組函式的深入理解

1. re.complie() 作用:如果需要重複地使用某個正則表示式,那麼你可以先將該正則表示式編譯成模式物件。complie()函式就幫助我們將正則表示式,編譯成為一個pattern物件。 2.re.search(pattern ,string) regex.search(strin

網路爬蟲必備知識之表示式

就庫的範圍,個人認為網路爬蟲必備庫知識包括urllib、requests、re、BeautifulSoup、concurrent.futures,接下來將結對re正則表示式的使用方法進行總結 1. 正則表示式概念   正則表示式是對字串操作的一種邏輯公式,就是用事先定義好的一些特定字元、及這些特定字

表示式-如何從一個字串拿到特定內容

做Web開發時,經常需要從一個訊息中去取得自己需要的欄位資訊,如果這個訊息是Json或XML型別那很方便。但如果是個字串呢,就像下面這樣: val str = “window.code=200;window.redirect_uri=\”wx.qq.co

VBA-表示式獲取網上資料

以貓眼電影為例 1,我們要獲得貓眼電影榜單的好看的電影資訊,影片名稱,主演,以及觀看和購票連結,獲取後效果如下圖所示 2.不難看出,我們只需要通過觀察網頁原始碼,然後進行整合提取關鍵資訊,在用正則表示式來擷取想要的資訊就可以對應的獲取相應的資訊,具體的程式碼及解釋如下

Python學習之路 (五)爬蟲(四)表示式爬去名言網

auth Python標準庫 我們 color 匯總 eight code 比較 school 爬蟲的四個主要步驟 明確目標 (要知道你準備在哪個範圍或者網站去搜索) 爬 (將所有的網站的內容全部爬下來) 取 (去掉對我們沒用處的數據) 處理數據(按照我們想要的

自學python爬蟲(三)表示式

一、什麼是正則表示式 正則表示式是對字串操作的一種邏輯公式,就是用事先定義好的一些特定字元,及這些特定字元的組合,組成一個“規則字串”,這個“規則字串”用來表達對字串的一種過濾邏輯。(非Python獨有,python中re模組實現) 二、常見的匹配模式 re.match

Python 核心程式設計學習——表示式

#正則表示式 首先明確一下學習正則表示式的初衷 讀完了蟲師的自動化實踐書,自己動手想寫一個介面測試,發現很多東西都不大會,很多地方卡死了,尤其卡在匹配字元上,師父讓我直接用index取出字元,程式碼感覺不大美觀。 正則表示式是一些有字元和特殊符號組成的字串,它們描述了模式的重複或者表述多

python爬蟲第五篇--表示式

Re模組正則表示式 概念 正則表示式是對字串串操作的⼀一種邏輯公式,就是⽤用事先定義好的⼀一些特定 字元、及這些特定字元的組合,組成⼀一個“規則字串串”,這個“規則字串串”⽤用 來表達對字串串的⼀一種過濾邏輯 非python獨有,re模組實現 re.

Python爬蟲實戰之Requests+表示式爬取貓眼電影Top100

import requests from requests.exceptions import RequestException import re import json # from multiprocessing import Pool # 測試了下 這裡需要自己新增頭部 否則得不到網頁 hea

python爬蟲(二)----表示式

正則表示式 本部落格主要講正則表示式在爬蟲網頁解析中的作用 需要的是python的re模組 python版本:3.x (一) 正則表示式的基本知識 1 匹配字元 常見匹配模式—匹配字元 模式 描述

python核心程式設計筆記——表示式(一)

文章目錄 特殊符號和字元 使用擇一匹配符號匹配多個正則表示式模式 匹配任意單個字元 從字串起始或結尾或單詞邊界匹配 建立字符集([]) 限定範圍與否定 使用閉包操作符實現存在性和頻數匹配(*\+\?) 表示

Python通過表示式獲取,去除(過濾)或者替換HTML標籤的幾種方法(本文由169it.com蒐集整理)

python正則表示式關鍵內容: python正則表示式轉義符: . 匹配除換行符以外的任意字元 \w 匹配字母或數字或下劃線或漢字 \s 匹配任意的空白符 \d 匹配數字 \b 匹配單詞的開始或結束 ^ 匹配字串的開始 $ 匹配字串的結束 \W 匹配任意不是字母,數字

python輸入框通過表示式的校驗

之前一直沒有用過正則表示式,這回需要校驗輸入框的輸入,看是否符合格式要求。 相容如“v1.0.0”和”1.0.0”的格式。臨時查了一下,就用上了。 程式碼如下,以便備查。 import re

Python爬蟲入門七之表示式

在前面我們已經搞定了怎樣獲取頁面的內容,不過還差一步,這麼多雜亂的程式碼夾雜文字我們怎樣把它提取出來整理呢?下面就開始介紹一個十分強大的工具,正則表示式! 1.瞭解正則表示式 正則表示式是對字串操作的一種邏輯公式,就是用事先定義好的一些特定字元、及這些

Python通過表示式和字串處理獲取方式獲取所需子字串的方式

       在爬蟲軟體時我們經常需要從url中尋找並獲取我們所需要的那一部分內容 此例我們需要從網址new_url= "http://news.sina.com.cn/c/gat/2017-06-14/doc-ifyfzfyz4058260.shtml"中獲取 fyfzf