Python 爬蟲第一篇(urllib+regex)

爬蟲的主要用途即從網(wǎng)站上獲取網(wǎng)頁,并將網(wǎng)頁中的有用信息解析出來。從網(wǎng)站上獲取網(wǎng)頁內(nèi)容可以通過 python 內(nèi)置的 urllib 模塊來實現(xiàn),至于信息的解析說起來比較復(fù)雜,python 中可以使用的模塊也有很多,今天我們主要使用正則表達式「python 內(nèi)置的 re 模塊」來實現(xiàn)數(shù)據(jù)的解析。

前面有對 python 內(nèi)置的 urllib 模塊和 re 模塊做過簡單的介紹有興趣的朋友可以了解一下

  1. 初識 Python 網(wǎng)絡(luò)請求庫 urllib
  2. Python 正則表達式

今天我們準(zhǔn)備使用 urllib 和 re 模塊來實現(xiàn)爬蟲的功能將網(wǎng)頁中的數(shù)據(jù)數(shù)據(jù)讀取出來。

確定目標(biāo)

我們的目標(biāo)是獲取立創(chuàng)商城上元器件的階梯價格「不同的采購數(shù)量對應(yīng)的價格不同」。先來看下網(wǎng)頁的圖片


image

我們想要的數(shù)據(jù)在這里


image

實施方案

首先我們可以后去到該網(wǎng)頁的網(wǎng)址 'https://item.szlcsc.com/213095.html'??梢允褂?urllib.urlopen 方法讀取網(wǎng)頁內(nèi)容

url = 'https://item.szlcsc.com/213095.html'
response = urllib2.urlopen(url)
html_text = response.read().decode('utf-8')

要獲取階梯價格的信息,我們先來看一下這段所對應(yīng)的 html 內(nèi)容:


image

從圖上可以看出每個階梯價格有 tr 標(biāo)簽進行分割,而每行的中的數(shù)量和對應(yīng)的價格使用 td 標(biāo)簽進行顯示。我們可以使用以下正則表達式來提取數(shù)量和價格內(nèi)容。

# 提取每個階梯價格的正則表達式
'<tr class="sample_list_tr">(.*?)</tr>'
# 提取一行中的數(shù)量
'<td width="40%" align="right">(.*?)</td>'
# 提取一行中的價格
"<p class='goldenrod'>(.*?)</p>"

現(xiàn)在我們來看一下完整的程序

# -*- coding:utf-8 -*-

import urllib2
import re

def find_number(str):
    '''
    獲取每一行中的數(shù)量范圍
    '''
    res = r'<td width="40%" align="right">(.*?)</td>'
    find_str = re.findall(res, str, re.S)[0]
    # 去除單位
    res_2 = '[1-9]{1}[\\d ~\\s]*\\d'
    find_str = re.findall(res_2, find_str, re.S)[0]
    # 去除字符串中的空格
    strinfo = re.compile('[\\s]')
    return re.sub(strinfo, '', find_str)

def find_price(str):
    '''
    獲取每一行中的價格信息
    '''
    res = r"<p class='goldenrod'>(.*?)</p>"
    find_str = re.findall(res, str, re.S)
    # 若無對應(yīng)的價格是顯示 None
    if len(find_str):
        # 去除價格中的單位
        res_2 = '[1-9]{1}[\\d\\.]*'
        find_str = re.findall(res_2, find_str[0], re.S)
        return find_str[0]
    else:
        return 'None'

url = 'https://item.szlcsc.com/213095.html'
# 讀取網(wǎng)頁內(nèi)容,并解碼相關(guān)內(nèi)容
response = urllib2.urlopen(url)
html_text = response.read().decode('utf-8')
res_tr = r'<tr class="sample_list_tr">(.*?)</tr>'
m_tr = re.findall(res_tr, html_text, re.S)
print '%4s |   %10s |  %5s' %('序號', '數(shù)量', '單價')
print "-------------------------"
for n, value in enumerate(m_tr):
    print '%4d | %10s | %5s' %(n + 1, find_number(value), find_price(value))
    print "-------------------------"

檢驗結(jié)果

代碼已經(jīng)編寫完成,現(xiàn)在我們來驗證一下執(zhí)行的效果,以上代碼的執(zhí)行結(jié)果如下:

序號 |       數(shù)量 |  單價
-------------------------
   1 |        1~9 |  9.21
-------------------------
   2 |      10~29 |  6.81
-------------------------
   3 |      30~99 |  6.37
-------------------------
   4 |    100~499 |  5.93
-------------------------
   5 |    500~999 |  5.73
-------------------------
   6 |       1000 |  5.64
-------------------------

對比執(zhí)行結(jié)果與前面我們看到的網(wǎng)頁信息,可以看到程序正常執(zhí)行且得到正確的結(jié)果。

想在我們將網(wǎng)址更換為 'https://item.szlcsc.com/8796.html',網(wǎng)頁顯示如下:

image

此時我們再次執(zhí)行程序,得到以下結(jié)果:

序號 |       數(shù)量 |  單價
-------------------------
   1 |        1~9 | 13.82
-------------------------
   2 |      10~29 | 11.75
-------------------------
   3 |      30~99 | 11.37
-------------------------
   4 |    100~499 | 10.99
-------------------------
   5 |    500~999 | 10.82
-------------------------
   6 |  1000~1999 | 10.61
-------------------------
   7 |       2000 |  None
-------------------------

可以看到以上結(jié)果與網(wǎng)頁中的內(nèi)容完全相同,代碼完成了我們的預(yù)定功能。

注意:此代碼在 python 2.7.10 版本驗證。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容