《用Python寫網路爬蟲》--編寫第一個網路爬蟲

zhujianing^_^發表於2017-03-30

編寫第一個python網路爬蟲

為了抓取網頁,首先要下載包含有感興趣資料的網頁,該過程一般被稱為爬取(crawing)。
本文主要介紹了利用sitemap檔案,遍歷ID,跟蹤網頁的方法獲取網頁內容。

下載網頁

想要爬取網頁,我們首先要將其下載下來。下載的指令碼如下:

import urllib2
def download(url):
    return urllib2.urlopen(url).read()

當傳入URL地址時,該函式將會下載並返回其HTML。
不過這個程式碼片存在一點問題,假如URL地址不存在時,urllib2就會丟擲異常。改進的版本為:

import urllib2
def download(url):
    try:
        html=urllib2.urlopen(url).read()
    except urllib2.URLError as e:
        print 'Downloading error:',e.reason
        html=None
    return html
print download('http://www.sse.com.cn')

下載時遇到的錯誤經常是臨時性的,比如伺服器過載時返回的503錯誤,對於此類錯誤,重新下載即可,下面是新增重新重新下載功能的程式碼:

import urllib2
def download(url,num_reload=5):
    try:
        html=urllib2.urlopen(url).read()
    except urllib2.URLError as e:
        print 'Downloading error:',e.reason
        html = None
        if num_reload>0 and ( hasattr(e,'code') and 500<=e.code<=600 ):
            return download(url,num_reload-1)
    return html

download('http://httpstat.us/500')

下面的這步可略過:

設定使用者代理

預設情況下,urllib2使用Python-urllib2/2.7作為使用者代理下載網頁內容,其中2.7是python的版本號。

import urllib2
def download(url,user_agent='wswp',num_reload=5):
    headers={'User-agent':user_agent}
    request=urllib2.Request(url,headers=headers)
    try:
        html=urllib2.urlopen(request).read()
    except urllib2.URLError as e:
        print 'Downloading error:',e.reason
        html = None
        if num_reload>0 and ( hasattr(e,'code') and 500<=e.code<=600 ):
            return download(url,user_agent,num_reload-1)
    return html

download('http://httpstat.us/500')

現在,我們有了一個靈活的函式,可以設定使用者代理,設定重試次數。

網站地圖爬蟲

使用robots.txt檔案中的網站地圖(即sitemap檔案)下載所有的網頁。
robots.txt
# section 1
User-agent: BadCrawler
Disallow: /
# section 2
User-agent: *
Crawl-delay: 5
Disallow: /trap
# section 3
Sitemap: http://example.webscraping.com/sitemap.xml
下面是使用sitemap檔案爬蟲的程式碼:

#!/usr/bin/python
#coding:utf-8
import urllib2
import re
def download(url,user_agent='wswp',num_reload=5):
    headers={'User-agent':user_agent}
    request=urllib2.Request(url,headers=headers)
    try:
        html=urllib2.urlopen(request).read()
    except urllib2.URLError as e:
        print 'Downloading error:',e.reason
        html = None
        if num_reload>0 and ( hasattr(e,'code') and 500<=e.code<=600 ):
            return download(url,user_agent,num_reload-1)
    return html

def crawl_sitemap(url):
    sitemap = download(url) #下載網頁檔案
    links = re.findall('<loc>(.*?)</loc>',sitemap) # 提取sitemap檔案裡的格式化連線
    for link in links:
        print link
        html = download(link)
       # print html

crawl_sitemap('http://example.webscraping.com/sitemap.xml')

下面是程式碼執行的效果:
《用Python寫網路爬蟲》--編寫第一個網路爬蟲

ID遍歷爬蟲

下面是一些示例國家的URL
http://example.webscraping.com/view/Afghanistan-1
http://example.webscraping.com/view/Aland-Islands-2
http://example.webscraping.com/view/Albania-3
http://example.webscraping.com/view/Algeria-4
http://example.webscraping.com/view/American-Samoa-5
http://example.webscraping.com/view/Andorra-6
http://example.webscraping.com/view/Angola-7
http://example.webscraping.com/view/Anguilla-8
可以看出,這些URL只在結尾處有區別。在URL中包含頁面別名是非常普遍的做法,可以對搜尋引擎起到優化的作用。一般情況下,Web伺服器會忽略這個字串,只用ID來匹配資料中的相關記錄。嘗試使用http://example.webscraping.com/view/-%d來匹配所有頁面。下面是示例程式碼:

#!/usr/bin/python
#coding:utf-8
import urllib2
import itertools
def download(url,user_agent='wswp',num_reload=5):
    headers={'User-agent':user_agent}
    request=urllib2.Request(url,headers=headers)
    try:
        html=urllib2.urlopen(request).read()
    except urllib2.URLError as e:
        print 'Downloading error:',e.reason
        html = None
        if num_reload>0 and ( hasattr(e,'code') and 500<=e.code<=600 ):
            return download(url,user_agent,num_reload-1)
    return html

for page in itertools.count(1):
    url='http://example.webscraping.com/view/%d'%page
    html=download(url)
    print url
    if html is None:
        break

連結爬蟲

本次將使用正規表示式來確定要下載哪些頁面。

相關文章