1. 程式人生 > >爬蟲專案:requests爬取豆瓣電影TOP250存入excel中

爬蟲專案:requests爬取豆瓣電影TOP250存入excel中

    這次爬取是爬取250部電影的相關內容,分別用了requests請求url,正則表示式re與BeautifulSoup作為內容過濾

openpyxl作為excel的操作模組,本人為才學不久的新手,程式碼編寫有點無腦和囉嗦,希望有大神能多提建議

    首先,程式碼清單如下:

import requests
import re
from bs4 import BeautifulSoup
import openpyxl
def get_movie_top250_name(soup):
    targets = soup.find_all('span',class_="title")           #用BeautifulSoup找尋一個內容為一個列表
    targets_name = re.findall(r'.*?title">(.*?)<\/span',str(targets))       #用正則表示式去掉標籤
    for each in targets_name:               #剔除targets_name當中的別名
        if '\xa0' in each:
            targets_name.remove(each)
    return targets_name

def get_movie_top250_workers(soup):
    targets = soup.find_all('p',class_="")
    targets_workers = []
    for each in targets:
        targets_workers.append(each.text.replace('<p class="">','').replace('\n                            ','').replace('\xa0','').replace('\n                        ',''))
    return targets_workers

def get_movie_top250_star(soup):
    targets = soup.find_all('div', class_="star")
    targets_star = re.findall(r'<span class="rating_num" property="v:average">(.*?)<\/span>',str(targets))
    return targets_star
def get_movie_top250_quote(soup):
    targets = soup.find_all('p', class_="quote")
    targets_quote = re.findall(r'<span class="inq">(.*?)<\/span>',str(targets))
    return targets_quote

def save_to_excel(name,workers,star,quote):

    wb = openpyxl.Workbook()
    ws =wb.active

    ws['A1'] = "電影名稱"
    ws['B1'] = "工作人員"
    ws['C1'] = "評分"
    ws['D1'] = "描述"
    for i in range(len(name)):
        result = [name[i],workers[i],star[i],quote[i]]
        ws.append(result)
    wb.save("豆瓣電影TOP250.xlsx")
def main():
    numbers = 1
    name = []
    workers = []
    star = []
    quote = []
    result = []
    while numbers:
        url = 'https://movie.douban.com/top250?start={}&filter='.format(numbers-1)
        headers = {'User-Agent':'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36'}
        res = requests.get(url,headers = headers)
        soup = BeautifulSoup(res.text, "html.parser")
        name_1 = get_movie_top250_name(soup)
        workers_1 = get_movie_top250_workers(soup)
        star_1 = get_movie_top250_star(soup)
        quote_1 = get_movie_top250_quote(soup)
        for i in range(len(name_1)):
            name.append(name_1[i])
            workers.append(workers_1[i])
            star.append(star_1[i])
            quote.append(quote_1[i])
        numbers += 25
        if numbers > 250:
            break
    save_to_excel(name,workers,star,quote)
if __name__ == '__main__':
    main()
    執行結果如下:


    其實一開始,有想過是不是直接用正則表示式找就行了,不用BeautifulSoup。然後完全是因為自己想多熟悉一下兩個的用法,所以都用到了,自認為兩個一起用能更準確些。首先談一談最重要的是碼程式碼時候遇到的一些問題:

1.抓取電影的名字:

def get_movie_top250_name(soup):
    targets = soup.find_all('span',class_="title")           #用BeautifulSoup找尋一個內容為一個列表
    targets_name = re.findall(r'.*?title">(.*?)<\/span',str(targets))       #用正則表示式去掉標籤
    for each in targets_name:               #剔除targets_name當中的別名
        if '\xa0' in each:
            targets_name.remove(each)
    return targets_name
比較容易被卡住的點就是電影名稱裡有許多的別名,如圖:                                                                                             

可以看出,每一個電影的class ='title'有兩個,這就不好分辨了。由於本人剛學不久,所以在篩選電影的名字的時候,就花了我半天時間。其實回想很簡單,如果把所有的名字print出來,就會發現別名前面都會有字元'\xa0',所以只要做一個if判斷的過濾就可以解決(當時if判斷也想了半天,結果問人才寫出來的,基礎不好,要補基礎大哭)。

2.爬取工作人員的內容,其中也包括電影的性質歸屬了,兩個一起抓了,其實我就是懶,沒有分開:

def get_movie_top250_workers(soup):
    targets = soup.find_all('p',class_="")
    targets_workers = []
    for each in targets:
        targets_workers.append(each.text.replace('<p class="">','').replace('\n                            ','').replace('\xa0','').replace('\n                        ',''))
    return targets_workers

這裡的抓取只用到了BeautifulSoup,然後做一個replace的過濾,將多餘的部分全部過濾(節點、空格之類的),比較簡單

3.抓取評分、描述(一句很騷的話描述了整個電影),都跟第二點差不多,略過

下一步計劃開始學習Scrapy框架抓取。。