1. 程式人生 > >Python爬蟲入門實戰系列(二)爬取貓眼電影排行榜

Python爬蟲入門實戰系列(二)爬取貓眼電影排行榜

在進行本節實戰之前,希望您對requests庫以及正則表示式有所瞭解。

執行平臺:windows
**Python版本: Python3.x **

一、依賴庫的安裝

在本節實戰之前,請確保已經正確安裝了requests庫
requests庫的安裝

pip3 install requests

如果您使用的是conda環境,可以選擇使用以下安裝方法

conda install requests

###二、抓取分析
貓眼電影TOP100的目標站點為http://maoyan.com/board/4?offset=0
這裡寫圖片描述
將網頁滾動到最下方,點選第二頁。
當網頁跳轉後,發現頁面的URL發生如下變化
這裡寫圖片描述
每一頁顯示的電影排名數目為10,而offset便代表著偏移量。
根據我們的推測,點選第三頁後,網頁URL中offset的值便會變成20,檢驗後沒有問題。
因此,我們想獲得TOP100的電影資訊,只需要分開請求10次,而這10次的offset引數分別設定為0,10,20…90即可。這樣獲取不同的頁面之後,利用正則表示式提取相關資訊,即可爬取電影排行榜電影資訊。

###三、實戰進行中
首先,我們引入我們需要的庫檔案

import requests
import re
import json
import time
from requests.exceptions import RequestException

爬取首頁

def get_one_page(url):
    try:
        headers = {'User-Agent':'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.62 Safari/537.36'}
        response = requests.get(url,headers=headers)
        if response.status_code == 200:
            return response.text
        return 0
    except RequestExceptrion:
        return 0

新增headers報頭進行爬蟲偽裝,利用requests.get函式發起請求
如果網頁返回碼為200(成功),則return response.text,返回頁面原始碼

我們來輸出一下網頁的原始碼看以下

print(get_one_page('http://maoyan.com/board/4?offset=0'))

執行後,如下圖所示
這裡寫圖片描述
說明我們爬取成功,接下來我們只需要從網頁原始碼裡匹配我們需要的資訊即可。

正則提取
【前提:瞭解貪婪匹配/非貪婪匹配】
利用開發者模式下的Network監聽元件可以檢視網頁的真實原始碼
這裡寫圖片描述
我們可以看到,一部電影對應的原始碼便是一個dd節點,我們利用正則表示式來提取裡面的電影資訊。
正則表示式寫法不唯一,只要能夠提取到資訊即可,在這裡我主要使用的是.*?匹配方法。
舉個例子:

<dd>.*?board-index.*?>(.*?)</i>

()裡的資訊便是我們匹配的資訊,在這裡我們匹配了排名,同樣的,電影名稱、演員表等資訊的匹配與之相同。
最後,正則表示式如下(不唯一,自己寫比較方便):

<dd>.*?board-index.*?>(.*?)</i>.*?title="(.*?)".*?img data-src="(.*?)".*?<p class="star">(.*?)</p>.*?releasetime">(.*?)</p>.*?integer">(.*?)</i><i class="fraction">(\d+).*?</dd>

在這裡我們匹配了電影排名,電影名稱,電影封面圖,演員表,上映時間,評分。
compile()
在進行後續操作前,先簡單講解一下compile()方法,這個方法可以將正則字串編譯成正則表示式物件,以便在後續的匹配中複用。
因此,我們使用compile()方法編譯物件:

    pattern = re.compile(
        '<dd>.*?board-index.*?>(.*?)</i>.*?title="(.*?)".*?img data-src="(.*?)".*?<p class="star">(.*?)</p>.*?releasetime">(.*?)</p>.*?integer">(.*?)</i><i class="fraction">(\d+).*?</dd>',re.S
    )

re.S是修飾符:使.匹配包括換行符在內的所有字元
因此解析頁面的函式實現如下:

def parse_one_page(html):
    pattern = re.compile(
        '<dd>.*?board-index.*?>(.*?)</i>.*?title="(.*?)".*?img data-src="(.*?)".*?<p class="star">(.*?)</p>.*?releasetime">(.*?)</p>.*?integer">(.*?)</i><i class="fraction">(\d+).*?</dd>',re.S
    )
    items = re.findall(pattern,html)
    print(items)

此時,我們將程式碼合併,便是如下

import requests
import re
import json
import time
from requests.exceptions import RequestException

def get_one_page(url):
    try:
        headers = {'User-Agent':'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.62 Safari/537.36'}
        response = requests.get(url,headers=headers)
        if response.status_code == 200:
            return response.text
        return 0
    except RequestExceptrion:
        return 0
        
def parse_one_page(html):
    pattern = re.compile(
        '<dd>.*?board-index.*?>(.*?)</i>.*?title="(.*?)".*?img data-src="(.*?)".*?<p class="star">(.*?)</p>.*?releasetime">(.*?)</p>.*?integer">(.*?)</i><i class="fraction">(\d+).*?</dd>',re.S
    )
    items = re.findall(pattern,html)
    print(items)

html = get_one_page('http://maoyan.com/board/4?offset=0')
parse_one_page(html)

執行結果如下

這裡寫圖片描述
可以看到,我們已經成功爬取了本頁內電影的資訊,但是資料比較雜亂,因此我們需要將匹配結果處理以下,遍歷提取結果並生成字典。
此時parse_one_page函式改下如下:

def parse_one_page(html):
    pattern = re.compile(
        '<dd>.*?board-index.*?>(.*?)</i>.*?title="(.*?)".*?img data-src="(.*?)".*?<p class="star">(.*?)</p>.*?releasetime">(.*?)</p>.*?integer">(.*?)</i><i class="fraction">(\d+).*?</dd>',re.S
    )
    items = re.findall(pattern,html)
    for item in items:
        yield{
            'index':item[0],
            'title':item[1],
            'image':item[2],
            'actor':item[3].strip()[3:] if len(item[3]) > 3 else '',
            'time':item[4].strip()[5:] if len(item[4]) > 5 else '',
            'score':item[5].strip()+item[6].strip(),
        }

輸入以下程式碼執行

html = get_one_page('http://maoyan.com/board/4?offset=0')
for item in parse_one_page(html):
    print(item)

這裡寫圖片描述
這樣每個電影的資訊便會成為一個個字典,形成結構化資料。

寫入檔案
寫入檔案我們分為txt寫入和csv檔案寫入。
首先我們來講txt檔案寫入。
txt
通過JSON庫的dumps()方法實現字典的序列化,並指定ensure_ascii引數為FALSE,這樣可以保證輸出結果是中文形式而不是Unicode編碼

def write_to_file(content):
    with open('maoyanSpider.txt','a',encoding='utf-8')as f:
        f.write(json.dumps(content,ensure_ascii=False)+'\n')

csv
寫入csv檔案的話,我們還需要引入csv庫。

import csv
def write_to_file(content):
    with open('maoyanSpider.csv','a+',newline='')as csvfile:
        writer = csv.writer(csvfile)
        values = list(content.values())
        writer.writerow(values)

使用content.values()方法讀取json資料,然後轉換成列表。
接著使用writerow()將values資料一次一行的寫入csv中
在open中newline=’ '是為了防止寫入資料後多出空白行。

分頁爬取
這也是爬蟲的最後一步了,我們之前的操作都是爬取一個頁面,而我們需要抓取的TOP100中含有10個頁面,所以還需要遍歷一下。

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

if __name__=='__main__':
    for i in range(10):
        spider(offset=10*i)
        time.sleep(1)

四、完整程式碼

爬取貓眼電影排行榜並存放於txt

import requests
import re
import json
import time
from requests.exceptions import RequestException

def get_one_page(url):
    try:
        headers = {'User-Agent':'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.62 Safari/537.36'}
        response = requests.get(url,headers=headers)
        if response.status_code == 200:
            return response.text
        return 0
    except RequestExceptrion:
        return 0


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

def parse_one_page(html):
    pattern = re.compile(
        '<dd>.*?board-index.*?>(.*?)</i>.*?title="(.*?)".*?img data-src="(.*?)".*?<p class="star">(.*?)</p>.*?releasetime">(.*?)</p>.*?integer">(.*?)</i><i class="fraction">(\d+).*?</dd>',re.S
    )
    items = re.findall(pattern,html)
    for item in items:
        yield{
            'index':item[0],
            'title':item[1],
            'image':item[2],
            'actor':item[3].strip()[3:] if len(item[3]) > 3 else '',
            'time':item[4].strip()[5:] if len(item[4]) > 5 else '',
            'score':item[5].strip()+item[6].strip(),
        }

def write_to_file(content):
    with open('maoyanSpider.txt','a',encoding='utf-8')as f:
        f.write(json.dumps(content,ensure_ascii=False)+'\n')

if __name__=='__main__':
    for i in range(10):
        spider(offset=10*i)
        time.sleep(1)

爬取貓眼電影排行榜並存放於csv

import requests
import re
import json
import time
from requests.exceptions import RequestException
import csv

def get_one_page(url):
    try:
        headers = {'User-Agent':'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.62 Safari/537.36'}
        response = requests.get(url,headers=headers)
        if response.status_code == 200:
            return response.text
        return 0
    except RequestExceptrion:
        return 0


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

def parse_one_page(html):
    pattern = re.compile(
        '<dd>.*?board-index.*?>(.*?)</i>.*?title="(.*?)".*?img data-src="(.*?)".*?<p class="star">(.*?)</p>.*?releasetime">(.*?)</p>.*?integer">(.*?)</i><i class="fraction">(\d+).*?</dd>',re.S
    )
    items = re.findall(pattern,html)
    for item in items:
        yield{
            'index':item[0],
            'title':item[1],
            'image':item[2],
            'actor':item[3].strip()[3:] if len(item[3]) > 3 else '',
            'time':item[4].strip()[5:] if len(item[4]) > 5 else '',
            'score':item[5].strip()+item[6].strip(),
        }

def write_to_file(content):
    with open('maoyanSpider.csv','a+',newline='')as csvfile:
        writer = csv.writer(csvfile)
        values = list(content.values())
        writer.writerow(values)

if __name__=='__main__':
    for i in range(10):
        spider(offset=10*i)
        time.sleep(1)

相關推薦

Python爬蟲入門實戰系列貓眼電影排行榜

在進行本節實戰之前,希望您對requests庫以及正則表示式有所瞭解。 執行平臺:windows **Python版本: Python3.x ** 一、依賴庫的安裝 在本節實戰之前,請確保已經正確安裝了requests庫 requests庫的安裝 pip3 i

Python3爬蟲入門實戰系列貓眼電影排行榜

在進行本節實戰之前,希望您對requests庫以及正則表示式有所瞭解。 執行平臺:windows Python版本: Python3.x 一、依賴庫的安裝 在本節實戰之前,請確保已經正確安裝了requests庫 requests庫的安裝 pip3 instal

Python爬蟲入門實戰系列--網路小說並存放至txt檔案

執行平臺: Windows  Python版本: Python3.x  一、庫檔案                      

scrapy入門實戰練習----豆瓣電影top250

轉自知乎網工具和環境語言:python 2.7IDE: Pycharm瀏覽器:Chrome爬蟲框架:Scrapy 1.2.1教程正文觀察頁面結構通過觀察頁面決定讓我們的爬蟲獲取每一部電影的排名、電影名稱、評分和評分的人數。宣告ItemItems爬取的主要目標就是從非結構性的資

python爬蟲實踐——零基礎快速入門豆瓣電影

爬蟲又稱為網頁蜘蛛,是一種程式或指令碼。 但重點在於,它能夠按照一定的規則,自動獲取網頁資訊。 爬蟲的基本原理——通用框架 1.挑選種子URL; 2.講這些URL放入帶抓取的URL列隊; 3.取出帶抓取的URL,下載並存儲進已下載網頁庫中。此外,講這些URL放入帶抓取UR

Python django 入門學習系列

1 . 繫結 URL 與檢視函式 2 .使用Django模板系統 這裡主要是跟著追夢的教程自己一邊看著一邊用於實踐來寫的 步驟1:首先在 專案應用的目錄下建立一個 urls.py 檔案 在urls.py 中寫入: blog/urls.p

部落格搬家系列-CSDN部落格

部落格搬家系列(二)-爬取CSDN部落格 一.前情回顧  部落格搬家系列(一)-簡介:https://blog.csdn.net/rico_zhou/article/details/83619152  部落格搬家系列(三)-爬取部落格園部落格:https://bl

Python爬蟲入門實戰--------一週天氣預報

    最近學校剛開始開設爬蟲課,我也剛剛如入門,嘗試寫了一個爬去成都市的一週的天氣預報。     目錄 一、軟體和庫的準備: 二、爬蟲的編寫: 三、全部程式碼 一、軟體和庫的準備: python環境安裝配置:安

Python開發簡單爬蟲---百度百科頁面數據

class 實例 實例代碼 編碼 mat 分享 aik logs title 一、開發爬蟲的步驟 1.確定目標抓取策略: 打開目標頁面,通過右鍵審查元素確定網頁的url格式、數據格式、和網頁編碼形式。 ①先看url的格式, F12觀察一下鏈接的形式;② 再看目標文本信息的

Python爬蟲框架Scrapy例項

目標任務:使用Scrapy框架爬取新浪網導航頁所有大類、小類、小類裡的子連結、以及子連結頁面的新聞內容,最後儲存到本地。 大類小類如下圖所示: 點選國內這個小類,進入頁面後效果如下圖(部分截圖): 檢視頁面元素,得到小類裡的子連結如下圖所示: 有子連結

python爬蟲常見面試題

前言   之所以在這裡寫下python爬蟲常見面試題及解答,一是用作筆記,方便日後回憶;二是給自己一個和大家交流的機會,互相學習、進步,希望不正之處大家能給予指正;三是我也是網際網路寒潮下崗的那批人之一,為了找工作而做準備。 一、題目部分 1、scrapy框架專題部分(很多面試都會涉及到這部分) (1

Python學習入門之列表

Python學習入門之列表(二) 初始化列表 names = ["zr","hc","ws","hj","fz"] 使用for迴圈遍歷整個列表 for name in names : print(name.upper) 建立數值列表 使用range函式生成

Netty4.x 原始碼實戰系列:服務端bind流程詳解

在上一篇《ServerBootstrap 與 Bootstrap 初探》中,我們已經初步的瞭解了ServerBootstrap是netty進行服務端開發的引導類。 且在上一篇的服務端示例中,我們也看到了,在使用netty進行網路程式設計時,我們是通過bind方法

python爬蟲之豆瓣圖片

偽裝瀏覽器 對與一些需要登入的網站,如果不是從六七發出的請求,則得不到響應。所以,我們需要將爬蟲程式法出請求偽裝成瀏覽器正規軍 具體實現:自定義網頁請求報頭(詳細介紹) 使用Fiddle檢視

SparkSQLSpark-1.4.0)實戰系列——DataFrames進階

本節主要內容如下 DataFrame與RDD的互操作實戰 不同資料來源構建DataFrame實戰 DataFrame與RDD的互操作實戰 1 採用反映機制進行Schema型別推導(RDD到DataFrame的轉換) SparkSQL支援RDD到D

Python爬蟲包 BeautifulSoup 學習 異常處理

面對網路不穩定,頁面更新等問題,很可能出現程式異常的問題,所以我們要對程式進行一些異常處理。大家可能覺得處理異常是一個比較麻煩的活,但在面對複雜網頁和任務的時候,無疑成為一個很好的程式碼習慣。 網頁‘404’、‘500’等問題 try:

Python爬蟲的法律邊界怡情,大over!

view 去年 大眾點評 項目 工具 挖掘 web服務器 多網站 use 數據抓取的門檻越來越低,會點程序,或使用網絡工具都可以薅點數據,新入行了不少爬蟲選手,但是對抓取使用數據的法律風險可能缺少認識。尤其是從去年的《網絡安全法》實施開始,被新聞公開報道的相關法律訴訟已有

python入門到放棄

python3 其他 產生 用戶 值方法 字母 str 是我 表示 編碼類型 ASCII碼:主要用來顯示英文和其他西歐語言,用8位來表示,也就是一個字節,最多只能顯示256個符號 UNICODE:也叫萬國碼,為了解決傳統的字符編碼方案的局限而產生的,它為每種語言的每個字符

IdentityServer4簡單入門demo系列 API資源端

續上篇 二、API資源端 1、新建專案 ApiReSource 用來存放需要被保護的API,如下圖   2、引用nuget裡的 IdentityServer4.AccessTokenValidation類庫    3、新增一個Controller名叫 TestController   

SpringBoot基礎實戰系列springboot解析json與HttpMessageConverter

# SpringBoot解析Json格式資料 ### @ResponseBody 注:該註解表示前端請求後端controller,後端響應請求返回 `json` 格式資料前端,實質就是將java物件序列化 #### 1.建立Controller 注:springboot預設就已經支援返回`json`格式資料,