此文爲你們入門爬蟲來作一次簡單的例子,讓你們更直觀的來了解爬蟲。
本次咱們利用 Requests 和正則表達式來抓取豆瓣電影的相關內容。html
咱們要提取出豆瓣電影-正在上映電影名稱、評分、圖片的信息,提取的站點 URL 爲:https://movie.douban.com/cinema/nowplaying/beijing/,提取的結果咱們以文件形式保存下來。git
確保已經正確安裝 Requests 庫,不管是 Windows、Linux 仍是 Mac,均可以經過 Pip 這個包管理工具來安裝。github
安裝命令:pip3 install requests
正則表達式相關教程見:正則表達式總結版、正則表達式正則表達式
抓取的目標站點爲:https://movie.douban.com/cinema/nowplaying/beijing/,打開以後即可以查看到正在上映的電影信息,如圖所示:頁面中顯示的有效信息有影片名稱、評分、圖片等信息。這樣咱們獲取該頁面結果以後再用正則表達式提取出相關信息就能夠獲得全部正在上映的電影信息了。json
接下來咱們用代碼實現抓取頁面源代碼過程,首先實現一個 get_page() 方法,傳入 url 參數,而後將抓取的頁面結果返回,而後再實現一個 main() 方法調用一下,初步代碼實現以下:
def get_page(url): try: response = requests.get(url) if response.status_code == 200: return response.text return None except RequestException: return None def main(): url = "https://movie.douban.com/cinema/nowplaying/beijing/" html = get_page(url)
----工具
接下來咱們回到網頁看一下頁面的真實源碼,在開發者工具中 Network 監聽,而後查看一下源代碼,如圖所示:注意這裏不要在 Elements 選項卡直接查看源碼,此處的源碼可能通過 JavaScript 的操做而和原始請求的不一樣,咱們須要從 Network 選項卡部分查看原始請求獲得的源碼。
查看其中的一個條目的源代碼如圖所示:能夠看到一部電影信息對應的源代碼是一個 li 節點,咱們用正則表達式來提取這裏面的一些電影信息,首先咱們須要提取它的電影名稱信息,而它的電影名稱信息是在 class 爲 "list-item"的節點後,因此這裏利用非貪婪匹配來提取data-title屬性的信息,正則表達式寫爲:
<li.*?list-item.*?data-title="(.*?)".*?>
使用相同判斷方法來提取data-score屬性的信息,正則表達式寫爲:post
<li.*?list-item.*?data-title="(.*?)".*?data-score="(.*?)".*?>
隨後咱們須要提取電影的圖片,能夠看到在a節點內部有img節點,該節點的src屬性是圖片的連接,因此在這裏提取img節點的src屬性,因此正則能夠改寫以下:編碼
<li.*?list-item.*?data-title="(.*?)".*?data-score="(.*?)".*?>.*?<img.*?src="(.*?)".*?/>
這樣咱們一個正則表達式能夠匹配一個電影的結果,裏面匹配了3個信息,接下來咱們經過調用 findall() 方法提取出全部的內容,實現一個 parse_page() 方法以下:url
def parse_page(html): pattern = re.compile('<li.*?list-item.*?data-title="(.*?)".*?data-score="(.*?)".*?>.*?<img.*?src="(.*?)".*?/>', re.S) items = re.findall(pattern, html) for item in items: yield{ 'title': item[0], 'score': item[1], 'image': item[2], }
這樣咱們就能夠成功提取出電影的圖片、標題、評份內容了,並把它賦值爲一個個的字典,造成結構化數據,運行結果以下:code
{'image': 'https://img3.doubanio.com/view/photo/s_ratio_poster/public/p2517753454.jpg', 'title': '復仇者聯盟3:無限戰爭', 'score': '8.6'} {'image': 'https://img1.doubanio.com/view/photo/s_ratio_poster/public/p2517769368.jpg', 'title': '小公主艾薇拉與神祕王國', 'score': '0'} {'image': 'https://img1.doubanio.com/view/photo/s_ratio_poster/public/p2519994468.jpg', 'title': '後來的咱們', 'score': '5.8'} {'image': 'https://img3.doubanio.com/view/photo/s_ratio_poster/public/p2520200484.jpg', 'title': '我是你媽', 'score': '5.1'} {'image': 'https://img3.doubanio.com/view/photo/s_ratio_poster/public/p2520197352.jpg', 'title': '戰犬瑞克斯', 'score': '7.0'}
到此爲止咱們就成功提取了此頁的電影信息。
隨後咱們將提取的結果寫入文件,在這裏直接寫入到一個文本文件中,經過 json 庫的 dumps() 方法實現字典的序列化,並指定 ensure_ascii 參數爲 False,這樣能夠保證輸出的結果是中文形式而不是 Unicode 編碼,代碼實現以下:
def write_to_file(content): with open('xiaoxi.txt', 'a', encoding='utf-8')as f: print(type(json.dumps(content))) f.write(json.dumps(content,ensure_ascii=False))
經過調用 write_to_json() 方法便可實現將字典寫入到文本文件的過程,此處的 content 參數就是一部電影的提取結果,是一個字典。
到此爲止,咱們 的爬蟲就所有完成了,再稍微整理一下,完整的代碼以下:源碼見git
# -*- coding: utf-8 -*- # @Time : 2018/5/12 上午11:37 # @Author : xiaoxi # @File : test.py import json import re import requests from requests import RequestException def get_page(url): try: response = requests.get(url) if response.status_code == 200: return response.text return None except RequestException: return None def parse_page(html): pattern = re.compile('<li.*?list-item.*?data-title="(.*?)".*?data-score="(.*?)".*?>.*?<img.*?src="(.*?)".*?/>', re.S) items = re.findall(pattern, html) for item in items: yield{ 'title': item[0], 'score': item[1], 'image': item[2], } def write_to_file(content): with open('xiaoxi.txt', 'a', encoding='utf-8')as f: # print(type(json.dumps(content))) f.write(json.dumps(content,ensure_ascii=False)) def main(): url = "https://movie.douban.com/cinema/nowplaying/beijing/" html = get_page(url) for item in parse_page(html): print(item) write_to_file(item) if __name__ == '__main__': main()
運行以後,能夠看到電影信息也已所有保存到了文本文件中,大功告成!
最後咱們運行一下代碼,相似的輸出結果以下:
{'image': 'https://img3.doubanio.com/view/photo/s_ratio_poster/public/p2517753454.jpg', 'title': '復仇者聯盟3:無限戰爭', 'score': '8.6'} {'image': 'https://img1.doubanio.com/view/photo/s_ratio_poster/public/p2517769368.jpg', 'title': '小公主艾薇拉與神祕王國', 'score': '0'} ... {'image': 'https://img1.doubanio.com/view/photo/s_ratio_poster/public/p2519994468.jpg', 'title': '後來的咱們', 'score': '5.8'}
中間的部分輸出結果已省略,能夠看到這樣就成功把電影信息爬取下來了。
這時咱們再看下文本文件,結果如圖所示:
以上~~你對爬蟲有進一步的瞭解了麼? 請繼續關注個人爬蟲系列~~~