Python 從零開始爬蟲(三)——實戰:requests+BeautifulSoup實現靜態爬取

前篇全片都是生硬的理論使用,今天就放個靜態爬取的實例讓你們體驗一下BeautifulSoup的使用,瞭解一些背後的原理。html

順便在這引入靜態網頁的概念——靜態網頁是指一次性加載全部內容的網頁,爬蟲一次請求便能獲得全部信息,對爬蟲很是友好,適合練手python

豆瓣top250電影信息爬取

這是一個老掉牙的經典實例了,但越是經典,越有示範性做用,最重要的一點是,它是靜態的。
給出網站:https://movie.douban.com/top250
打開F12/右鍵檢查第一個電影,分析源碼先,發現每一個<li>標籤就對應着一個電影的信息。
圖片描述程序員

咱們來爬取每部電影的圖片,名稱,導演演員,類型,評分,和它的一句話總結,繼續對<li>標籤進行分析,又發現信息又在<div class="info">標籤裏,而這標籤只存在於<li>標籤中,其它地方不存在,這樣能夠用find_all()方法把他們所有分離出來。這裏不選擇<li>標籤是它沒有惟一性,電影之外的內容也有<li>標籤正則表達式

圖片描述

佈置好假裝後就可一開始根據每一個<div class="info">標籤進行信息篩選了:markdown

  • 圖片連接是<div class="info">的上上個兄弟標籤<div class="pic">的孫子<img>的src屬性的值
  • 電影名有多個,都在<div class="hd">標籤裏,用get_text()把它們串起來
  • 導演演員是<p class>標籤的第一段字符串
  • 類型是<p class>標籤的第二段字符串
  • 評分和評分人數都在<div class="star">標籤裏,又用get_text()串起來
  • 一句話總結直屬於<span class="inq">標籤
  • html中的&NBSP(其實是小寫,這裏大寫避免markdown識別)對應字符串中的\xa0,可用replace方法替換掉
url = 'https://movie.douban.com/top250'
headers = {'User-Agent' : 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.108 Safari/537.36'}
r=requests.get(url,headers=headers)
soup = BeautifulSoup(r.text,'lxml')

for each in soup.find_all('div',class_='info'):
    img_url = each.previous_sibling.previous_sibling.a.img['src']#圖片連接
    
    '''with open('*.jpg','wb') as img:#還能夠順便下載回來,名字自起
    img.write(requests.get(img_url,headers=headers).content)'''
    
    
    title=each.find('div',class_='hd').get_text(strip=True).replace('\xa0','')#標題
    actor = list(each.find('p',class_='').strings)[0].strip().replace('\xa0','')#導演演員
    type_ = list(each.find('p',class_='').strings)[1].strip().replace('\xa0','')#類型
    score = each.find('div',class_='star').get_text('/',strip=True)#評分及人數
    quote = each.find('span',class_='inq').string#一句話總結
    print([img_url,title,actor,type_,score,quote])#這裏只簡單打出來看下,怎樣存儲由你來決定

  可是這樣只有25部電影啊,是的,'https://movie.douban.com/top250'指向第一頁,咱們如今只爬了一頁,其實還有9頁還沒爬啊,這是就要構造網址了。網站

  咱們點到第二頁,發現網址變成了https://movie.douban.com/top2...,第三頁start條件值變成50,咱們能夠得出結論,每下一頁,start條件值就加25。第一頁start=0,第二頁start=25.....第十頁start=225。這樣就能夠循環構造網頁並爬取了,這交給讀者實現
  下面筆者提供另外一種思路:網頁不是有下一頁的按鈕嗎,右鍵檢查一下,發現它已經包含了要構造的部分了,是一個屬性值,提取出來接到原網址上即獲得下一頁的網址,這樣能徹底爬取全部頁數,不用像上面同樣設置循環次數。
圖片描述url

貼上完整代碼spa

import requests
from bs4 import BeautifulSoup


url = 'https://movie.douban.com/top250'
with open('douban.txt','w',encoding='utf-8') as f:
    while url :
        headers = {'User-Agent' : 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.108 Safari/537.36'}

        r=requests.get(url,headers=headers)
        soup = BeautifulSoup(r.text,'lxml')

        for each in soup.find_all('div',class_='info'):
            img_url = each.previous_sibling.previous_sibling.a.img['src']
            title=each.find('div',class_='hd').get_text(strip=True).replace('\xa0','')
            actor = list(each.find('p',class_='').strings)[0].strip().replace('\xa0','')
            #將生成器list化後索引,strip()去除兩邊空格再用空字符替換&nbsp
            type_ = list(each.find('p',class_='').strings)[1].strip().replace('\xa0','')
            score = each.find('div',class_='star').get_text('/',strip=True)
            if each.find('span',class_='inq'):#注意有部電影沒有總結,也就沒有<span class="inq">標籤這裏用if檢測一下防止None使用string方法報錯
                quote = each.find('span', class_='inq').string
            else:
                quote = '沒有總結哦'
            print([img_url,title,actor,type_,score,quote])

            try:#到最後一頁時沒有下一頁按鈕,會報TypeError,這時用try語句讓url=None使while循環中止
                url = 'https://movie.douban.com/top250' + soup.find('span',class_='next').a['href']
            except TypeError:
                url = None

本實例的篩選方法已經講的很細緻了,幾乎說起了BeautifulSoup的全部方法,但願你們能經過此實例能加深對BeautifulSoup的理解,而後本身手打一些爬蟲出來,小的十幾行多的幾十行均可以,爬貼吧什麼的均可以。code

仍是那句話「只看不實踐的程序員不是好程序員xml

下一篇應該會將正則表達式,更增強大也更加難的信息匹配方法下下篇瞭解一下動態爬取?

相關文章
相關標籤/搜索