零基礎(chǔ)爬蟲實戰(zhàn)(Python):抓取豆瓣電影TOP250

? 學(xué)習(xí)了《簡明Python教程》,然后想著實戰(zhàn)一下,搜索了一些資料,然后對豆瓣電影排行250進行了一個抓取,后續(xù)還會對數(shù)據(jù)進行一些分析。

? 這篇文章主要是對抓取豆瓣電影top250過程的一個梳理,方便日后自己查閱,也希望可以方便到有需要的人。

? 下面是整個抓取過程的思維導(dǎo)圖:

爬取豆瓣電影TOP250.png

1. 生成URL信息

? 首先觀察豆瓣電影TOP250的網(wǎng)頁地址,多點開幾頁,就能發(fā)現(xiàn)規(guī)律。每一頁都是展示了25個電影。

2. 分析網(wǎng)頁標(biāo)簽

? 這個就是對網(wǎng)頁html文件的解析了,可以先在網(wǎng)頁中瀏覽目標(biāo)信息,然后在網(wǎng)頁的源碼中通過搜索查找到相應(yīng)的標(biāo)簽。最后一定要搞清楚定位每一個目標(biāo)信息標(biāo)簽的方式。

? 我在這是采用的是BeautifulSoup對html進行的解析。

3. 請求網(wǎng)頁數(shù)據(jù)

? 我是使用urllib.request中的urlopen()方法對網(wǎng)頁進行請求的。

urlopen(url).read().decode('utf-8')

? urlopen(url)獲取到的是HTTPResponse對象,然后調(diào)用read()方法獲得網(wǎng)頁的字節(jié)數(shù)據(jù),字節(jié)數(shù)據(jù)沒法直接處理,所以最后調(diào)用decode('utf-8')方法將獲取的字節(jié)對象編碼成文本字符串(string)

4. 存儲信息

? 先把數(shù)據(jù)生成pandas庫的DataFrame對象,然后調(diào)用其to_csv()方法將數(shù)據(jù)存儲到csv文件中,非常的方便。

完整的代碼

? 算是自己完成了第一個小的爬蟲程序,以后會在此基礎(chǔ)上不斷的擴展與完善。下面是獲取豆瓣電影TOP250的Python完整代碼。

# encoding=utf-8

from collections import defaultdict
from urllib.request import urlopen
from bs4 import BeautifulSoup
import pandas as pd
import time
import re


class DoubanMovieTop250:
    # 生成url和相應(yīng)存儲最終數(shù)據(jù)的容器
    def __init__(self):
        self.top250_urls = ['https://movie.douban.com/top250?start={0}&filter='.format(i * 25) for i in range(10)]
        self.data = defaultdict(list)
        self.columns = ['title', 'link', 'score', 'score_cnt', 'top_no', 'directors', 'writers', 'actors', 'types',
                        'edit_location', 'language', 'dates', 'play_location', 'length', 'rating_per',
                         'betters', 'had_seen', 'want_see', 'tags', 'review', 'ask', 'discussion']
        self.df=None

    def get_info(self):
        for url in self.top250_urls:
            # 將獲取的網(wǎng)頁封裝成BeautifulSoup
            print(url)
            html = urlopen(url).read().decode('utf-8')

            bsobj = BeautifulSoup(html)

            # 開始解析網(wǎng)頁中的數(shù)據(jù)
            main = bsobj.find('ol', {'class': 'grid_view'})


            # 標(biāo)題及鏈接信息
            title_obj = main.findAll('div', {'class': 'hd'})
            titles = [ i.find('span', {'class': 'title'}).text for i in title_obj]
            links = [ i.find('a')['href'] for i in title_obj]

            # 評分信息
            score_obj = main.findAll('div', {'class': 'star'})
            scores = [i.find('span', {'class': 'rating_num', 'property': 'v:average'}).text for i in score_obj]
            score_cnts = [ i.findAll('span')[-1].text for i in score_obj]

            # 將解析到的數(shù)據(jù)存入到容器中
            for title, link, score, score_cnt in zip(titles, links, scores, score_cnts):
                self.data[title].extend([title, link, score, score_cnt])
                # 解析更多、更詳細的信息
                more_data = self.get_more_info(link)
                self.data[title].extend(more_data)
                print(self.data[title])
                print(len(self.data))
                time.sleep(1)

    def get_more_info(self, link):
        html = urlopen(link).read().decode('utf-8')
        bsobj = BeautifulSoup(html)

        # 榜單排名 top_no
        top_no = bsobj.find('span', {'class': 'top250-no'}).text

        # 導(dǎo)演 directors
        main = bsobj.find('div', {'id': 'info'})
        directors = [i.text for i in main.findAll('a', {'rel': 'v:directedBy'})]

        # 編劇 writers 可能沒有編劇
        try:
            writers = [i.text for i in main.findAll('span', {'class': 'attrs'})[1].findAll('a')]
        except Exception as ex:
            writers = []
            print(ex)

        # 主演 actors 可能沒有主演
        try:
            actors_obj = main.findAll('a', {'rel': 'v:starring'})
            actors = [i.text for i in actors_obj]
        except Exception as ex:
            actors = []
            print(ex)

        # 類型 types
        types_obj = main.findAll('span', {'property': 'v:genre'})
        types = [i.text for i in types_obj]

        # 制片地區(qū) edit_location
        pattern = re.compile('地區(qū):(.*)\n語言', re.S)
        edit_location = re.findall(pattern, main.text)[0]

        # 語言 language
        pattern2 = re.compile('語言:(.*)\n上映日期', re.S)
        language = re.findall(pattern2, main.text)[0]


        # 上映日期和地區(qū)  dates play_location
        date_boj = main.findAll('span', {'property': 'v:initialReleaseDate'})
        dates = [i['content'].split('(')[0] for i in date_boj]
        play_location = [i['content'].split('(')[1] for i in date_boj]

        # 片長 length
        length = main.find('span', {'property': 'v:runtime'})['content']

        # 5星到1星的比例 rating_per 一共是5個數(shù)字
        rating_per = [i.text for i in bsobj.findAll('span', {'class': 'rating_per'})]

        # 好于 betters
        better_obj = bsobj.find('div', {'class': 'rating_betterthan'}).findAll('a')
        betters = [i.text for i in better_obj]


        # 想看/看過 had_seen want_see
        fit_obj = bsobj.find('div', {'class': 'subject-others-interests-ft'})
        had_seen = fit_obj.find('a').text[:-3]
        want_see = fit_obj.findAll('a')[1].text[:-3]

        # 標(biāo)簽 tags
        tags = [i.text for i in bsobj.find('div', {'class': 'tags-body'}).findAll('a')]

        # 短評 review  (有多少個短評)
        review = bsobj.find('div', {'id': 'comments-section'}).find('h2').find('a').text

        # 問題 ask (有多少個問題)
        ask = bsobj.find('div', {'id': 'askmatrix'}).find('a').text.strip()

        # 討論 discussion (有多少個討論)
        discussion = bsobj.find('p', {'class': 'pl', 'align':'right'}).find('a').text.strip().split('(')[1][2:-2]

        more_data=[top_no, directors, writers, actors, types, edit_location, language, dates, play_location, length, rating_per, betters, had_seen, want_see,tags, review, ask, discussion]
        return more_data

    # 存儲數(shù)據(jù)到csv文件
    def dump_data(self):
        data = []
        for title, value in self.data.items():
            data.append(value)
            self.df=pd.DataFrame(data, columns=self.columns)
            self.df.to_csv('exercise_douban_movie_Top250.csv')


if __name__ == '__main__':
    douban = DoubanMovieTop250()
    douban.get_info()
    douban.dump_data()

參看資料:零基礎(chǔ)Python爬蟲實戰(zhàn):豆瓣電影TOP250

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容