爬蟲體驗

做者:桂。css

時間:2017-02-14  12:29:34html

連接:http://www.cnblogs.com/xingshansi/articles/6397083.html python

聲明:轉載請註明出處,謝謝。web


前言正則表達式

網上一些數據一個個下載/複製太慢,爬蟲是個不錯的工具,先接觸一下,用到了再研究。chrome

 1、安裝明細數據庫

  • Wins 8.1,64位
  • Anaconda集成安裝;
  • 版本:Anaconda3-4.1.0-Windows-x86_64.exe-,默認python 3.5版本
Anaconda可經過下面的連接下載:

選用Anaconda主要考慮:windows

  • 不須要配置PYTHON環境變量;
  • 集成不少packages,省去一一下載的麻煩;
  • packages的安裝很簡單,conda一鍵解決;
  • 能夠配置python3.5版本的環境,方便切換,互不干擾,兼容性強。

Anaconda官網有相應的文檔介紹:瀏覽器

2、Python簡介服務器

  A-編輯器選擇

網上有各類IDE推薦,起步定位是:熟悉功能,編寫直接採用Anaconda自帶的spyder

  B-工具包安裝

Python工具包的下載主要經過運行Anaconda Prompt

該模塊主要基於 conda指令,關於conda的細節,能夠參考:

用到的packages主要包括:

  • urllib
  • requests
  • beautifulsoup
  • scrapy

requests具備良好的樹狀分析特性,能夠省區正則表達式帶來的麻煩,打算從urllib學起,先熟悉爬蟲的通常特性,若是加載成功,則說明對應的packages已經install完成。

  C-程序管理

Run—>Configure,設置.py文件的存儲路徑:

3、頁面爬取(如下基於python2.7, 3.5相似)

跳出細節信息,先想一想爬取須要哪些操做:

  • 爬取網頁內容
  • 定位目標信息連接
  • 讀取連接,並將讀取的內容寫入本地/數據庫

步驟一:爬取頁面信息

打開網頁的流程能夠簡化爲:HTTP是用戶發出請求—>對方返回協議—>頁面解析並顯示。

對於某風景網站,藉助python基本的爬取代碼:

import urllib2

def download(url):
    headers = {'User-Agent':"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.1 (KHTML, like Gecko) Chrome/22.0.1207.1 Safari/537.1"}
    request = urllib2.Request(url,headers = headers)
    try:
       html = urllib2.urlopen(request).read()
    except urllib2.URLError as e:
        print 'error:', e.reason
        html = None
    return html

url = 'http://www.onlytease.com/'
page = download(url)
print page

  關於解碼信息,打開網頁並按F12,在head下拉單裏便可看到編碼方式,解碼與其對應。

至此,對於基本的網頁已經實現爬取功能,然而滿頁內容,只有極少數是本身關心的,對於基本框架的搭建僅剩一個問題:如何爬取本身想要的內容。

步驟二:定位目標信息

打開任意網頁(以chrome爲例),選中感興趣的內容,右鍵:檢查(或快捷鍵:Crtl + shift + I),既能夠查看對應的細節信息:

例如選中一張圖片: 

 

 電腦User-agent的查看方式不少,能夠直接登錄網站

這是人爲觀察的方式,若是但願自動定位目標信息能夠經過正則表達式、beautifulsoup等工具。經常使用正則表達式參考這篇文章

步驟三:寫入目標內容

先撇開前面兩個步驟,以圖片爲例,網上能夠搜索python 網頁 圖片下載。看看具體的操做,文本/壓縮包等文件以此類推。

url = 'http://pics.sc.chinaz.com/files/pic/pic9/201705/bpic1322.jpg'
f = open('1.jpg',"wb")    #命名並打開文件  
req = urllib2.urlopen(url)  
buf = req.read()              #讀出文件  
f.write(buf)                  #寫入文件 

 這樣網上的圖片就進入了本地:

 爬取小圖片:

code:

import urllib2
import re

def download(url): #Step1:讀取網頁內容
    headers = {'User-Agent':"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.1 (KHTML, like Gecko) Chrome/22.0.1207.1 Safari/537.1"}
    request = urllib2.Request(url,headers = headers)
    try:
       html = urllib2.urlopen(request).read()
    except urllib2.URLError as e:
        print 'error:', e.reason
        html = None
    return html
#Step2:獲取目標信息連接,我要的是jpg的連接
url = 'http://sc.chinaz.com/tupian/fengjingtupian.html'
page = download(url)
imglist = re.findall('src2="(.*?)"',page)      #re.findall() 方法讀取html 中包含 imgre(正則表達式)的    數據
#Step3:文件保存至本地
i = 1
for imgname in imglist:
    f = open('.\\sightsee\\'+str(i)+'.jpg',"wb")    #命名並打開文件  
    print i
    i = i+1
    req = urllib2.urlopen(imgname)  
    buf = req.read()              #讀出文件  
    f.write(buf)                  #寫入文件 

  收入囊中:

爲何是src2而不是src,複製download的文本到txt文件,搜索.jpg,

看到是src2,但網頁裏是src:

上面爬取的是一頁的圖片,若是想獲取總共的呢?能夠經過正則表達式匹配並計算總頁數,這裏爲了方面觀察一下:

打開網站,http://sc.chinaz.com/tupian/,發現總共是2217頁:

除了第一頁有點不一樣:

其它依次類推:

好了,如今進一步完善代碼:

import urllib2
import re
import numpy as np

def download(url): #Step1:讀取網頁內容
    headers = {'User-Agent':"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.1 (KHTML, like Gecko) Chrome/22.0.1207.1 Safari/537.1"}
    request = urllib2.Request(url,headers = headers)
    try:
       html = urllib2.urlopen(request).read()
    except urllib2.URLError as e:
        print 'error:', e.reason
        html = None
    return html
urllen = 2217
tag = np.arange(1,urllen+1)
base = 'http://sc.chinaz.com/tupian/'
i = 1
for j in tag:   
    if j==1:
        url = base+'index.html'
    else:
        url = base+'index_'+str(j)+'.html'
    page = download(url)
    imglist = re.findall('src2="(.*?)"',page)      #re.findall() 方法讀取html的.jpg連接
    for imgname in imglist:
        f = open('.\\sightsee\\'+str(i)+'.jpg',"wb")    #命名並打開文件  
        print i
        i = i+1
        req = urllib2.urlopen(imgname)  
        buf = req.read()              #讀出文件  
        f.write(buf)                  #寫入文件         
        f.close()    

  都已經成功下載出來了:

有一個問題:

沒有設置timeout參數,結果在網絡環境很差的狀況下,時常出現read()方法沒有任何反應的問題,程序卡死在read()方法裏,給urlopen加上timeout就ok了,設置了timeout以後超時以後read超時的時候會拋出socket.timeout異常,想要程序穩定,還須要給urlopen加上異常處理,再加上出現異常重試。

修改這一句:

html = urllib2.urlopen(request,timeout=2).read()

  問題就解決了。

但仍是會有其餘錯:

 參考下面的圖片,添加異常處理,問題解決。

 

4、渲染動態網頁爬取

python的工具包均可以在這裏下載。安裝selenium工具包,安裝lxml,python2中須要單獨下載:cssselect,顧名思義,css+select就是前段css樣式select。

這裏僅僅記錄應用,偷個懶:用selenium+phantomjs的爬取方式。

phantomjs簡介:

PhantomJS 是一個基於 WebKit 的服務器端 JavaScript API。它全面支持web而不需瀏覽器支持,其快速,原生支持各類Web標準: DOM 處理, CSS 選擇器, JSON, Canvas, 和 SVG。 PhantomJS 能夠用於 頁面自動化 , 網絡監測 , 網頁截屏 ,以及 無界面測試 等。

不少網頁不一次性把內容加載完,若是每次都刷新頁面又不理想,所以藉助動態加載,看到哪裏只加載這一部份內容。phantomjs能夠不用經過打開瀏覽器,卻得到了網頁加載後的內容,這樣再用urllib2.request操做讀取就能夠獲取網頁的整個內容,而不是沒有動態加載的內容。

兩點注意:

1-phantomjs的\bin須要在環境變量PATH裏添加絕對路徑;

2-代碼裏:路徑前要添加r

browser = webdriver.PhantomJS(executable_path=r"C:\Users\Nobleding\Anaconda3\Lib\site-packages\phantomjs-2.1.1-windows\bin\phantomjs.exe")
#coding=utf-8


from selenium import webdriver
import re
import urllib2

browser = webdriver.PhantomJS(executable_path=r"C:\Users\Nobleding\Anaconda3\Lib\site-packages\phantomjs-2.1.1-windows\bin\phantomjs.exe")
browser.implicitly_wait(50)
#browser.get("https://www.baidu.com/")
urllink = "網址名稱"
browser.get(urllink)
page = browser.execute_script("return document.documentElement.outerHTML")
imglist = re.findall('src=(.*?).jpg', page)      #re.findall() 方法讀取html的.jpg連接
i=1
for imgname in imglist:
    f = open('.\\sightsee\\'+str(i)+'.jpg',"wb")    #命名並打開文件 
    print i
    i = i+1
    try:
        imglink = imgname+'.jpg'
        n = len(imglink)
        req = urllib2.urlopen(imglink[1:n],timeout = 3)
    except urllib2.URLError, e:
        print 'error:', e.reason
        continue
    except socket.error as e:
        continue
    except socket.timeout as e:   
        continue
    except urllib2.HTTPError:
        continue
    buf = req.read()              #讀出文件 
    f.write(buf)                  #寫入文件
    f.close()

  基於urllib2/urllib3/urllib常常會報timeout錯,直接用requests更直接,且再也不報time out錯誤:

# -*- coding: utf-8 -*-
"""
Created on Sun May 07 09:48:39 2017

@author: Nobleding
"""

import requests
import re
import socket
import numpy as np
import urllib
from socket import timeout

def download(url): #Step1:讀取網頁內容
    header = {'User-Agent':"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.1 (KHTML, like Gecko) Chrome/22.0.1207.1 Safari/537.1"}
#    request = requests.Request(url,headers = headers)
    try:
       htmll = requests.get(url,headers=header)
       html = htmll.text
#    except requests.URLError:
#        print ('error:')
#        html = None
    except socket.error as e:
        html = None
    except socket.timeout as e:   
        html = None
    except urllib.request.HTTPError:
        html = None
    return html
urlmain =網址
pagemain = download(urlmain)
#pagemain = pagemain.decode('utf-8')
imglistmain = re.findall('<a href=\'/pictures/(.*?)/\'',pagemain)
i=1
nums = np.arange(0,len(imglistmain)+1)
for j in nums:
    url = urlmain+imglistmain[j]+'/'
    print (111)
    page = download(url)
    if page == None:
        continue
    else:
#        page = page.decode('utf-8')
        imglist = re.findall('src=(.*?).jpg',page)
    for imgname in imglist:
        f = open('.\\sightsee\\'+str(i)+'.jpg',"wb")    #命名並打開文件
        print (i)
        i = i+1
        try:
            imglink = imgname+'.jpg'
            nlen = len(imglink)
            req = requests.get(imglink[1:nlen],timeout = 5)
#        except requests.URLError:
#            print ('error:')
#            continue
        except timeout:
#            print(e)
            continue
        except socket.error as e:
#            prin1t(e)
            continue
#        buf = req.read()              #讀出文件
        f.write(req.content)                  #寫入文件
        f.close() 

總結一下,之後須要python爬取內容,須要提到的地方:

  • 網頁讀取:若是有JS動態加載以及驗證碼、帳號密碼登cookies等問題,須要進一步深刻
  • 目標信息獲取:須要注意兩方面——
    • 快速定位目標信息,須要熟悉正則表達式、beautifulsoup工具包或者其餘高級輔助工具
    • 異常狀況處理:如等待時間過長、爬取速度過快被管理員監視、進入死循環等等問題,須要調研彙總並研究解決,如:
    • 嵌套的處理:好比經過A網頁能夠打開B網頁,而內容C的連接要在B網頁進一步獲取,依次類推
  • 內容的存儲
    • 須要熟悉不一樣格式文件的存儲方法,如文本、pdf、PPT、壓縮文件、視頻、音樂、圖片等等經常使用格式的存儲辦法
    • 若是數據過大,且須要與他人共享,須要涉及並行下載、數據庫等方面的知識
相關文章
相關標籤/搜索