python-入門的第一個爬蟲例子


前言:

此文為大家入門爬蟲來做一次簡單的例子,讓大家更直觀的來了解爬蟲。
本次我們利用 Requests 和正則表達式來抓取豆瓣電影的相關內容。


一、本次目標:

我們要提取出豆瓣電影-正在上映電影名稱、評分、圖片的信息,提取的站點 URL 為:https://movie.douban.com/cinema/nowplaying/beijing/,提取的結果我們以文件形式保存下來。


二、准備工作

確保已經正確安裝 Requests 庫,無論是 Windows、Linux 還是 Mac,都可以通過 Pip 這個包管理工具來安裝。

安裝命令:pip3 install requests
正則表達式相關教程見:正則表達式總結版正則表達式


三、抓取分析

抓取的目標站點為:https://movie.douban.com/cinema/nowplaying/beijing/,打開之后便可以查看到正在上映的電影信息,如圖所示:20180512142639_result.png頁面中顯示的有效信息有影片名稱、評分、圖片等信息。這樣我們獲取該頁面結果之后再用正則表達式提取出相關信息就可以得到所有正在上映的電影信息了。


四、抓取頁面源代碼

接下來我們用代碼實現抓取頁面源代碼過程,首先實現一個 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 監聽,然后查看一下源代碼,如圖所示:20180512142636_result.png注意這里不要在 Elements 選項卡直接查看源碼,此處的源碼可能經過 JavaScript 的操作而和原始請求的不同,我們需要從 Network 選項卡部分查看原始請求得到的源碼。
查看其中的一個條目的源代碼如圖所示:20180512143404_result.png可以看到一部電影信息對應的源代碼是一個 li 節點,我們用正則表達式來提取這里面的一些電影信息,首先我們需要提取它的電影名稱信息,而它的電影名稱信息是在 class 為 "list-item"的節點后,所以這里利用非貪婪匹配來提取data-title屬性的信息,正則表達式寫為:

<li.*?list-item.*?data-title="(.*?)".*?>

使用相同判斷方法來提取data-score屬性的信息,正則表達式寫為:

<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() 方法如下:

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],
        }

這樣我們就可以成功提取出電影的圖片、標題、評分內容了,並把它賦值為一個個的字典,形成結構化數據,運行結果如下:

{'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'}

中間的部分輸出結果已省略,可以看到這樣就成功把電影信息爬取下來了。
這時我們再看下文本文件,結果如圖所示:20180512143407_result.png


以上~~你對爬蟲有進一步的了解了么? 請繼續關注我的爬蟲系列~~~


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM