我寫了一個(gè)爬蟲…

前幾天在大神指導(dǎo)下動(dòng)手寫了年輕人第一個(gè)算得上程序的程序混驰。
一個(gè)豆瓣電影 TOP250 爬蟲
完整代碼已經(jīng)開源碌奉,放在我的 GitHub

Mindnode

網(wǎng)絡(luò)爬蟲

什么是網(wǎng)絡(luò)爬蟲俊性?

用人話講,爬蟲就是一個(gè)從互聯(lián)網(wǎng)上抓取信息的程序螃壤,比如我們需要一些電影信息,可以上新聞網(wǎng)站筋帖,或者我們需要一些新聞奸晴,可以上新聞網(wǎng)站,當(dāng)然我們最多的是使用搜索引擎幕随,關(guān)于搜索引擎后邊會(huì)講到蚁滋。
當(dāng)然這只在獲取少量信息的時(shí)候管用,如果我想要找的有幾千幾萬條的信息呢赘淮,這時(shí)候靠人工就顯得太費(fèi)時(shí)了。當(dāng)我們想獲取數(shù)據(jù)睦霎,只要網(wǎng)絡(luò)上有的梢卸,都可以通過爬蟲程序去抓取,所以爬蟲就是一種獲取數(shù)據(jù)的程序副女。

當(dāng)我們上網(wǎng)的時(shí)候蛤高,我們?cè)诟墒裁矗?/h2>

下邊以我們經(jīng)常用來測(cè)試網(wǎng)絡(luò)的一個(gè)網(wǎng)站為例
當(dāng)我們?cè)跒g覽器中輸入baidu.com按下回車之后發(fā)生了什么?

  1. 瀏覽器會(huì)自動(dòng)幫我們補(bǔ)齊https://www.baidu.com
  2. 瀏覽器首先向 DNS 服務(wù)器請(qǐng)求了baidu.com對(duì)應(yīng)的 IP 地址碑幅;
  3. 瀏覽器得到 IP 地址之后戴陡,就會(huì)向這個(gè)地址發(fā)送一個(gè) HTTP 請(qǐng)求;
  4. 然后從百度的服務(wù)器端請(qǐng)求到首頁(yè)的 HTML 源碼沟涨;
  5. 最后通過瀏覽器引擎解析源碼恤批,再次向服務(wù)器發(fā)請(qǐng)求得到里面引用的 Javascript、CSS裹赴、圖片啊一些資源喜庞,最后就得到了百度首頁(yè)。

爬蟲要干什么棋返?

大多數(shù)情況下延都,爬蟲其實(shí)就是在模擬上面說的過程。
當(dāng)然爬蟲不會(huì)全部模擬一遍睛竣,而是會(huì)選擇合適的步驟模擬晰房。
比如大多數(shù)情況下只需要請(qǐng)求 HTML 源碼,并不需要請(qǐng)求 CSS 和 Javascript 射沟。在得到源碼后殊者,就像瀏覽器會(huì)解析 HTML 源碼一樣,爬蟲也會(huì)解析 HTML躏惋,然后篩選出我們想要的內(nèi)容保存幽污。

爬蟲在哪兒?

  • 最大的爬蟲是什么簿姨?
    當(dāng)然是 Goolge距误,百度等等這些搜索引擎簸搞,當(dāng)然這種說法只是通俗意義上的,搜索引擎大致分為下載系統(tǒng)准潭、分析系統(tǒng)趁俊、索引系統(tǒng)和查詢系統(tǒng),爬蟲是搜索引擎的第一道門檻刑然。

  • 再譬如寺擂,據(jù)說有幾億人在用的新聞客戶端,沒錯(cuò)泼掠,就是今日頭條怔软,其就是依靠爬蟲,在網(wǎng)易新聞择镇、騰訊新聞挡逼、搜狐新聞和其他新聞網(wǎng)站上爬取新聞數(shù)據(jù),雖然這種做法有點(diǎn)不道德吧…

爬蟲有什么用腻豌?

  • 第一個(gè)例子是一個(gè)另類的資訊 APP——即刻家坎,它不制造新聞,也不同今日頭條無節(jié)操的從友商那拿東西吝梅,他完全可以自己定制或是選擇別人已經(jīng)制作好的話題來進(jìn)行追蹤虱疏,比如什么電腦病毒在全世界爆發(fā)了,像這些天鬧得比較火熱的比特幣病毒苏携,比如宮崎駿新作的最新消息啦做瞪,比如誰誰誰男神女神點(diǎn)贊微博了,又比如哪部電視劇更新了兜叨,這么多的提醒如果完全靠人工編輯審核那不得累死穿扳,估計(jì)即刻都活不過幾個(gè)月,但是這些提醒大多數(shù)靠的并不是人工国旷,而是網(wǎng)絡(luò)爬蟲矛物,這些爬蟲從社交網(wǎng)絡(luò),比如微博跪但,從視頻網(wǎng)站履羞,從其他地方抓取想要的信息然后推送。

  • 第二個(gè)例子也是一個(gè) App —— Price Tag屡久,一個(gè) IOS 上的查價(jià) App忆首,也是一位在杭州的獨(dú)立開發(fā)者 61 開發(fā)的,他就利用了爬蟲在 App Store 服務(wù)器中爬取應(yīng)用的價(jià)格被环,然后將 App 的價(jià)格用圖表的形式直觀的顯示出來糙及。當(dāng)然你也會(huì)說爬取到價(jià)格之后有什么用呢?說的直白點(diǎn)筛欢,如何變現(xiàn)呢浸锨?還是以 Price Tag 為例唇聘,61 在兩方面進(jìn)行變現(xiàn),一個(gè)是通過 App 的內(nèi)購(gòu)柱搜,還有一個(gè)是通過和 Apple 合作迟郎,獲取聯(lián)盟令牌,這樣用戶在 Price Tag 中查詢點(diǎn)擊進(jìn)行的購(gòu)買行為聪蘸,61 就能分到 7% 的傭金宪肖。

Python

什么是 Python?

從我的感官來說健爬,Python 是一種類似于我們學(xué)過的 C 和 C++ 的高級(jí)語(yǔ)言控乾,但其語(yǔ)法比 C 和 C++ 簡(jiǎn)單的多的多。
同時(shí)浑劳,Python 更多的又被叫做腳本語(yǔ)言阱持。
Python 被大量應(yīng)用于 WEB 開發(fā)中,比如在國(guó)內(nèi)不存在的網(wǎng)站 YouTuBe魔熏、Instagram,還有小資文藝聚集地豆瓣鸽扁、知乎蒜绽、果殼,這些都是完全用 Python 開發(fā)的桶现,為什么呢躲雅?

因?yàn)槲乃嚽嗄甓几F,所有東西都得一個(gè)人搞骡和,于是就只能用 Python 了相赁。
——這是在知乎上看到的一個(gè)回答

當(dāng)然這不只是說笑,從這個(gè)回答也可以看出 Python 的強(qiáng)悍慰于,因?yàn)樗母鱾€(gè)模塊都是現(xiàn)成的 钮科,拿過來就能用,不用像 C++ 那樣要用到一個(gè)模塊還得自己去寫婆赠。

為什么選擇 Python绵脯?

  • 其一:語(yǔ)法簡(jiǎn)單
    舉個(gè)實(shí)例,完成一個(gè)最簡(jiǎn)單的程序休里,顯示請(qǐng)輸入你的名字然后從鍵盤輸入名字最后顯示Hello蛆挫,名字

    用 C 語(yǔ)言寫

    #include<stdio.h>`
    #include<string.h>`
    int main()
    {
    char name[20];
    printf(“Please enter U name:”);
    scanf(“%s”,name);
    printf(“Hello,%s”,name);
    }
    

    用 C++ 寫

    #include<iostream>
    #include<string>
    using namespace std;
    int main()
    {
    char name[20];
    cout<<“Please enter U name:”<<endl;
    cin>>name;
    cout<<“Hello,”<<name<<endl;
    }
    

    用 Python 寫

    print('Hello,',input('Please enter U name:'))
    

    結(jié)果顯而易見

  • 其二:Python 有成熟的爬蟲腳本語(yǔ)言,正因?yàn)槭悄_本語(yǔ)言妙黍,編寫調(diào)試方便悴侵,而且有多線程更加高效。

豆瓣電影 TOP250 實(shí)戰(zhàn)

搭建開發(fā)環(huán)境

我在這里裝了 Python 3.6
接著再需要安裝兩個(gè)第三方庫(kù)拭嫁,Requests 和 BeautifulSoup
Requests 用于處理 HTTP 請(qǐng)求可免;
BeautifulSoup 用來解析 HTML 源碼抓于;
這兩個(gè)庫(kù)在接下來會(huì)用到。

分析 HTML 結(jié)構(gòu)

開發(fā)環(huán)境搭建完成巴元,編寫爬蟲之前毡咏,我們需要先思考爬蟲需要干什么?目標(biāo)網(wǎng)站有什么特點(diǎn)逮刨。
今天我們的目標(biāo)是把豆瓣電影 TOP250網(wǎng)站上所有的電影名稱呕缭,上映年份,評(píng)分修己,拍攝地區(qū)和電影簡(jiǎn)介爬下來恢总。
先打開豆瓣電影 TOP250,檢查分析網(wǎng)站源碼睬愤。

OK片仿,在 HTML 源碼中我們可以得到一些信息了。

  • 每頁(yè)有25條電影尤辱,共有10頁(yè)砂豌。
  • 電影列表在頁(yè)面上的位置為一個(gè)class屬性為grid_viewol標(biāo)簽中。
  • 每條電影信息放在這個(gè)ol標(biāo)簽的一個(gè)li標(biāo)簽里光督。
  • 電影名稱放在一個(gè)class屬性為titlespan標(biāo)簽中阳距。
  • 上映年份,拍攝地區(qū)放在一個(gè)class屬性為bddiv標(biāo)簽下的一個(gè)p標(biāo)簽中结借。
  • 評(píng)分放在一個(gè)class屬性為stardiv標(biāo)簽下的一個(gè) class 屬性為rating_numspan標(biāo)簽中筐摘。

下載網(wǎng)頁(yè)源碼

import requests as r
url = 'https://movie.douban.com/top250'
html = r.get(url).text
print(html)

只需要三句,最后一句打印出來用來判斷下載源碼是否成功船老。
網(wǎng)頁(yè)源碼已經(jīng)在控制臺(tái)打印出來咖熟。

解析網(wǎng)頁(yè)

OK,當(dāng)我們拿到網(wǎng)頁(yè)源碼之后柳畔,就需要解析 HTML 源碼了馍管。
這里,我們使用 BeautifulSoup 來搞定這件事荸镊。

import requests as r
from bs4 import BeautifulSoup as bs
url = 'https://movie.douban.com/top250'
html = r.get(url).text
items = bs(html).find_all('div','item')
for item in items:
    movie_name = item.find('span','title').string
    movie_rating = item.find('span','rating_num').string
    movie_quote = item.find('span','inq').string
    movie = (movie_name,movie_rating,movie_quote)
    print(str(movie))

正則表達(dá)式

電影名稱咽斧,評(píng)分,簡(jiǎn)介就在父標(biāo)簽中躬存,從電影信息的父標(biāo)簽匹配就可以拿到张惹,但是上映年份和拍攝地區(qū)和其他的信息一起在一個(gè)父標(biāo)簽中,無法單獨(dú)拿出來岭洲,這時(shí)候就需要用到正則表達(dá)式了宛逗。
如何從這里取出上映年份呢,年份都是四個(gè)數(shù)字吧盾剩,所有只要取出四個(gè)數(shù)字雷激,用正則表達(dá)式是 \d{4}
那拍攝地區(qū)又該怎么取出呢替蔬?拍攝地區(qū)在兩個(gè)斜杠之間,所以我們只要取出兩個(gè)斜杠之間的信息屎暇,所以正則表達(dá)式是 (?<=\d./).*(?=/)
這邊解釋一下
(?<=\d./) 匹配1個(gè)數(shù)字后面跟斜杠承桥,但是輸出結(jié)果不包含斜杠
(?=/) 匹配后面跟斜杠,但是輸出不包括斜杠根悼。
.* 代表除換行符外任意字?jǐn)?shù)的任意字符

movie_info = item.find('div','bd').find('p','').get_text()
movie_year = re.findall('\d{4}',movie_info)[0]
movie_nation = re.findall('(?<=\d./).*(?=/)',movie_info)[0]

如何翻頁(yè)

到這一步凶异,我們已經(jīng)得到了當(dāng)前頁(yè)想要的數(shù)據(jù),那么如何處理翻頁(yè)的問題呢挤巡?

  • 第一個(gè)想到辦法是找到頁(yè)碼導(dǎo)航頁(yè)的“下一頁(yè)”的鏈接剩彬,也很容易實(shí)現(xiàn)。
  • 第二個(gè)辦法是觀察 URL 結(jié)構(gòu)發(fā)現(xiàn)的
    所以可以用列表推導(dǎo)的方式來實(shí)現(xiàn)翻頁(yè)
url = ['https://movie.douban.com/top250?start={}'.format(str(i)) for i in range(0,226,25)]

多線程

在完成基本的架構(gòu)之后矿卑,就要開始進(jìn)行優(yōu)化了喉恋。
爬蟲一定要多線程,不然當(dāng)爬大量數(shù)據(jù)時(shí)就太慢了
比如說母廷,如果你用單線程發(fā)送一個(gè)請(qǐng)求轻黑,那必須在等結(jié)果返回之后再去發(fā)送下一個(gè)請(qǐng)求,而多線程呢琴昆,在發(fā)送完一個(gè)請(qǐng)求之后苔悦,不用等到結(jié)果返回,繼續(xù)發(fā)送下一個(gè)請(qǐng)求椎咧,這樣就減少了 CPU 的等待時(shí)間,也提高了 CPU 的使用效率把介。

拼裝

OK勤讽,到了最后一步,完成寫入模塊后把程序拼裝成一個(gè)完整的程序拗踢。但這個(gè)時(shí)候又遇到了一個(gè)問題脚牍,每次都只能爬到 107 個(gè)數(shù)據(jù),之后就開始報(bào)錯(cuò)巢墅。
然后進(jìn)網(wǎng)站去看了第 108 個(gè)數(shù)據(jù)诸狭,發(fā)現(xiàn)……

……

這丫的瘋狂動(dòng)物城沒有簡(jiǎn)介……
所以在簡(jiǎn)介這里加個(gè)判斷進(jìn)去。
OK君纫,到這里一段完整的豆瓣電影 TOP250 爬蟲就寫完了驯遇。

#!/usr/bin/env python
# encoding=utf-8

from bs4 import BeautifulSoup as bs
import requests as r
import csv
import re
import codecs
from multiprocessing.dummy import Pool
movies = []
url = ['https://movie.douban.com/top250?start={}'.format(str(i)) for i in range(0,226,25)]
def soup(url):
    html = r.get(url).text
    items = bs(html).find_all('div','item')
    for item in items:
        movie_name = item.find('span','title').string
        movie_rating = item.find('span','rating_num').string
        try:
            movie_quote = item.find('span','inq').string
        except:
            movie_quote='none'
        movie_info = item.find('div','bd').find('p','').get_text()
        movie_year = re.findall('\d{4}',movie_info)[0]
        movie_nation = re.findall('(?<=\d./).*(?=/)',movie_info)[0]
        movie = (movie_name,movie_year,movie_rating,movie_nation,movie_quote)
        #print(str(movie))
        movies.append(movie)

pool = Pool()
pool.map(soup, url)
pool.close()
pool.join()

with codecs.open('DoubanMovieTOP250.csv','w','utf-8',newline='') as csvfile:
    writer = csv.writer(csvfile)
    writer.writerow(["電影名稱","上映年份","評(píng)分","地區(qū)","簡(jiǎn)介"])
    writer.writerows(movies)

運(yùn)行

運(yùn)行程序,生成一個(gè) CSV 文件蓄髓。

CSV

數(shù)據(jù)淺析

篩選結(jié)果
  • 電影拿走不謝叉庐,請(qǐng)叫我雷鋒
  • 美國(guó),中國(guó)会喝,日本上榜電影排前三
  • 主要的電影內(nèi)容:信仰陡叠,青春玩郊,科幻,情懷等
  • 電影數(shù)最多的幾年為 1995~2013枉阵,近幾年電影較少译红,總結(jié)了一下原因,大概是:雖然制片投入和電影效果越來越好兴溜,但內(nèi)容卻沒以前那么好了侦厚,換句話說,人人可以當(dāng)導(dǎo)演的年代昵慌,編劇才是最重要的假夺。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市斋攀,隨后出現(xiàn)的幾起案子已卷,更是在濱河造成了極大的恐慌,老刑警劉巖淳蔼,帶你破解...
    沈念sama閱讀 216,324評(píng)論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件侧蘸,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡鹉梨,警方通過查閱死者的電腦和手機(jī)讳癌,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,356評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來存皂,“玉大人晌坤,你說我怎么就攤上這事〉┐” “怎么了骤菠?”我有些...
    開封第一講書人閱讀 162,328評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)疤孕。 經(jīng)常有香客問我商乎,道長(zhǎng),這世上最難降的妖魔是什么祭阀? 我笑而不...
    開封第一講書人閱讀 58,147評(píng)論 1 292
  • 正文 為了忘掉前任鹉戚,我火速辦了婚禮,結(jié)果婚禮上专控,老公的妹妹穿的比我還像新娘抹凳。我一直安慰自己,他們只是感情好踩官,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,160評(píng)論 6 388
  • 文/花漫 我一把揭開白布却桶。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪颖系。 梳的紋絲不亂的頭發(fā)上嗅剖,一...
    開封第一講書人閱讀 51,115評(píng)論 1 296
  • 那天,我揣著相機(jī)與錄音嘁扼,去河邊找鬼信粮。 笑死,一個(gè)胖子當(dāng)著我的面吹牛趁啸,可吹牛的內(nèi)容都是我干的强缘。 我是一名探鬼主播,決...
    沈念sama閱讀 40,025評(píng)論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼不傅,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼旅掂!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起访娶,我...
    開封第一講書人閱讀 38,867評(píng)論 0 274
  • 序言:老撾萬榮一對(duì)情侶失蹤商虐,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后崖疤,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體秘车,經(jīng)...
    沈念sama閱讀 45,307評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,528評(píng)論 2 332
  • 正文 我和宋清朗相戀三年劫哼,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了叮趴。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,688評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡权烧,死狀恐怖眯亦,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情般码,我是刑警寧澤搔驼,帶...
    沈念sama閱讀 35,409評(píng)論 5 343
  • 正文 年R本政府宣布,位于F島的核電站侈询,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏糯耍。R本人自食惡果不足惜扔字,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,001評(píng)論 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望温技。 院中可真熱鬧革为,春花似錦、人聲如沸舵鳞。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,657評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至抛虏,卻和暖如春博其,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背迂猴。 一陣腳步聲響...
    開封第一講書人閱讀 32,811評(píng)論 1 268
  • 我被黑心中介騙來泰國(guó)打工慕淡, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人沸毁。 一個(gè)月前我還...
    沈念sama閱讀 47,685評(píng)論 2 368
  • 正文 我出身青樓峰髓,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親息尺。 傳聞我的和親對(duì)象是個(gè)殘疾皇子携兵,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,573評(píng)論 2 353

推薦閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,070評(píng)論 25 707
  • ある執(zhí)事の日常 執(zhí)事の日常 悪魔の実情 泡一杯提神的熱紅茶 烘烤面包煎制雞蛋卷 沒用的仆人們也需要好好調(diào)教一番 焦...
    凜櫻念蝶閱讀 566評(píng)論 2 6
  • 4.29 對(duì)我來說,幸福就是即使在一個(gè)陌生的地方身邊有他在的那種用語(yǔ)言難以描述的安心搂誉,也是相濡以沫的安靜徐紧,在一起的...
    梵希小姐閱讀 520評(píng)論 0 0
  • 電視劇《偽裝者》曾經(jīng)風(fēng)靡一時(shí),除了主演是胡歌勒葱、靳東浪汪、王凱三大帥哥,其中人物關(guān)系的扎實(shí)鋪陳凛虽、情節(jié)的跌宕起伏死遭,更是將這...
    CuiGeek閱讀 1,090評(píng)論 4 3