1. 程式人生 > >requests正則表示式爬取貓眼電影

requests正則表示式爬取貓眼電影

目標

通過Request+正則表示式爬取貓眼電影TOP100電影的排名、名字、電影封面圖片、主演、上映時間、貓眼評分,將爬取的內容寫入檔案中。

流程框架

進入到貓眼電影TOP100的頁面,此時的URL為http://maoyan.com/board/4,點選第2頁,會發現此時的URL為http://maoyan.com/board/4?offset=10,點選第3頁,會發現URL變成了http://maoyan.com/board/4?offset=20,由此可以推斷出offset引數為偏移量,如果偏移量為n,則顯示電影序號就是n+1到n+10,每頁顯示10個,所以,如果想獲取TOP100電影,只需要分開請求10次,而10次的offset引數分別設定為0、10、20......90即可,這樣獲取不同的頁面之後,再用正則表示式提取出相關資訊,就可以得到TOP100的所有電影資訊了。獲取資訊後,可以將資訊寫入txt檔案,當然可以存入資料庫(此處為了偷懶,就不存入資料庫了)。為了加快爬取網頁的速度,可以開啟迴圈和多執行緒(當需要爬取的資訊很大時,這是一個不錯的技巧)。

下圖展示了具體的流程框架:

(1)抓取單頁內容

# 獲取單個頁面的HTML程式碼
def get_one_page(url):
    try:
        # 此處如果不加headers進行偽裝,將會返回403錯誤(拒絕訪問)
        headers = {
            "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.99 Safari/537.36"
        }
        response = requests.get(url, headers = headers)
        # 如果返回的狀態碼是200,表示請求正常,返回頁面HTML程式碼
        # 否則,返回None
        if response.status_code == 200:
            return response.text
        return None
    except RequestException:
        return None

接下來測試一下是否可以獲取頁面內容:

if __name__ == '__main__':
    url = 'http://maoyan.com/board/4'
    html = get_one_page(url)
    print(html)

(2)正則表示式分析

可以對get_one_page(url)函式爬取的HTML程式碼進行分析(此處為了方便觀看,直接在瀏覽器控制檯分析),利用正則表示式獲取到有用的資訊(電影的排名、名字、電影封面圖片、主演、上映時間、貓眼評分)。

# 解析單個頁面的HTML程式碼,利用re模組提取出有效資訊
def parse_one_page(html):
    # re.S:表示“.”的作用擴充套件到整個字串,包括“\n”
    pattern = re.compile('<dd>.*?board-index.*?>(\d+)</i>.*?data-src="(.*?)".*?name"><a'
                +'.*?>(.*?)</a>.*?star">(.*?)</p>.*?releasetime">(.*?)</p>.*?integer">'
                +'(.*?)</i>.*?fraction">(.*?)</i>.*?</dd>', re.S)
    items = re.findall(pattern, html)
    for item in items:
        # 構造生成器函式
        yield{
            'index': item[0],
            'image': item[1],
            'title': item[2],
            'actor': item[3].strip()[3:],
            'time': item[4].strip()[5:],
            'score': item[5]+item[6]
        }

接下來測試一下是否可以得到我們想要的內容:

if __name__ == '__main__':
    url = 'http://maoyan.com/board/4'
    html = get_one_page(url)
    items = parse_one_page(html)
    for item in items:
        print(item)

控制檯輸出如下:

單個頁面資訊解析正確,那麼,想要獲得多個頁面的資訊,只需寫一個迴圈遍歷即可:

def main(offset):
    url = 'http://maoyan.com/board/4?offset=' + str(offset)
    html = get_one_page(url)
    for item in parse_one_page(html):
        print(item)

if __name__ == '__main__':
    for i in range(10):
        main(i*10)

(3)儲存至檔案

只需寫一個簡單的函式即可完成,但此處需要注意一點,為保證輸出檔案為中文,在讀寫檔案時要新增引數endcoding="utf-8"。

# 將解析出的內容寫入檔案
def write_to_file(content):
    # 新增endcoding="utf-8"確保輸出到檔案中為中文
    with open('result.txt', 'a', encoding='utf-8 ') as f:
        # 此處建議將解析出的內容編碼為json格式再寫入檔案,json的好處在此不過多敘述
        # 如果使用了json進行編碼,務必新增引數ensure_ascii=False確保編碼資料為中文
        # json.dumps():編碼json資料
        f.write(json.dumps(content, ensure_ascii=False) + '\n')
        f.close()

執行程式碼,目標資訊被寫入result.txt檔案中:

(4)開啟迴圈及多執行緒

為了加快頁面爬取速度,可以使用多執行緒(針對大量資料時非常有效)。

if __name__ == '__main__':
    pool = Pool()
    pool.map(main, [i*10 for i in range(10)])

專案完整程式碼已託管到github:https://github.com/panjings/python-spider