初識python及數(shù)據(jù)爬取

初識python

作為一位前端開發(fā)人員访递,一直以來,接觸最多的也都是html同辣,css拷姿,js;有時(shí)候會需要搭建一些node服務(wù)器邑闺,寫一些node后臺代碼跌前,僅此而已;

而python陡舅,只是在以前使用某些軟件時(shí)抵乓,需要python環(huán)境,就安裝到了電腦,然后灾炭,從來都沒有真正的接觸過它茎芋;

隨著數(shù)據(jù)分析、深度學(xué)習(xí)蜈出、機(jī)器學(xué)習(xí)的發(fā)展田弥,也讓我開始了python的學(xué)習(xí)之旅;雖然都說铡原,不管是什么語言偷厦,基本上都是相通的;但是對于一種你從未接觸過的語言燕刻,基礎(chǔ)只泼,還是非常重要的;所以卵洗,我還是默默的打開了瀏覽器请唱,在百度中搜索了“python基礎(chǔ)教程”,最后找到了Python 基礎(chǔ)教程 | 菜鳥教程过蹂,在這里面十绑,有環(huán)境的搭建、基本語法酷勺、數(shù)據(jù)類型本橙、常用函數(shù)等非常基礎(chǔ)的教程鸥印,我覺得非常適合我這種從來沒有接觸過的人勋功;隨后,我花了幾個(gè)小時(shí)的時(shí)間库说,將這里面基礎(chǔ)教程的所有內(nèi)容看了一遍狂鞋,在看的過程中,也跟著做了一些練習(xí)潜的;

雖然說骚揍,看了基礎(chǔ)教程,也頂多你大概能夠使用python進(jìn)行一些簡單的運(yùn)算而已啰挪;而作為開發(fā)人員信不,都明白一個(gè)道理,最好亡呵、最快的學(xué)習(xí)一種語言的方式當(dāng)然是從一個(gè)簡單的項(xiàng)目開始抽活,自己能夠從頭開始做一個(gè)自己覺得有意思但是難度不是很大的東西,這樣锰什,不僅能夠讓自己能夠更快的去理解這種語言下硕,而且丁逝,會使自己更有學(xué)習(xí)的動力和信心;因此梭姓,我開始了一個(gè)簡單的網(wǎng)站的數(shù)據(jù)爬取的實(shí)現(xiàn)霜幼,因?yàn)閷τ谖疫@種前端出生的人來說,與瀏覽器打交道誉尖,與網(wǎng)頁打交道罪既,相對來說,簡單很多铡恕;

開始

首先琢感,我肯定不知道從何處開始,因此探熔,我只能繼續(xù)百度“python 爬蟲”猩谊;最后找到了這篇文章“Python爬蟲實(shí)戰(zhàn)二之爬取百度貼吧帖子”,為什么選擇它呢?只有一個(gè)原因祭刚,在它的文章最后,有完整的代碼墙牌,我沒去看里面的描述涡驮,而是,直接用sublime直接創(chuàng)建了一個(gè)名為

$ pachong.py

的文件喜滨,然后將代碼全部拷貝進(jìn)去(雖然說可能代碼根本運(yùn)行不通)捉捅;

隨后,我開始了我的爬蟲之旅虽风,一開始棒口,我就直接在拷貝的代碼基礎(chǔ)上直接修改,而不同的是它爬取的是百度貼吧辜膝,我爬取的是汽車之家无牵。然后代碼就在這兒pachong.py(由于代碼較多,就不直接貼出來了厂抖,有興趣的茎毁,可以直接點(diǎn)鏈接進(jìn)github查看);在這里面有個(gè)很坑的地方忱辅,它的所有篩選自己需要數(shù)據(jù)的方式是通過正則匹配的方式實(shí)現(xiàn)的七蜘,而我什么也不知道的跟著學(xué)著,也使用正則墙懂,讓我為了從整個(gè)html中篩選自己需要的橡卤,花費(fèi)了太多的時(shí)間,而且效果一般损搬;但是后面才發(fā)現(xiàn)碧库,已經(jīng)有很完善的專門匹配頁面內(nèi)容方式的Python庫BeautifulSoup(這是它的中文文檔鏈接)柜与;

使用BeautifulSoup重寫

當(dāng)發(fā)現(xiàn)了BeautifulSoup之后,簡單看了一篇BeautifulSoup教程谈为,看完之后旅挤,如獲至寶,因?yàn)樗氖褂梅绞嚼锩嬗泻芏嗪颓岸死锩嫒カ@取元素伞鲫,獲取節(jié)點(diǎn)有異曲同工之妙粘茄;而我最喜歡使用的,是里面的“CSS選擇器”方式秕脓,簡直和前端使用jquery一模一樣柒瓣,比如:

通過標(biāo)簽名查找

print soup.select('p')

通過類名查找

print soup.select('.sister')

通過 id 名查找

print soup.select('#link1')

......等等;

因此吠架,我果斷選擇使用BeautifulSoup對上面最初的版本進(jìn)行重寫芙贫,尤其是在對內(nèi)容的篩選;而這一次傍药,我選擇了去爬取“螞蜂窩”的游記磺平;

作為前端開發(fā)的我,對于Chrome DevTools的使用拐辽,簡直是易如反掌拣挪;所以很容易就可以找出怎么去獲取自己需要的內(nèi)容(到底是用類名查找還是id查找,或者是什么組合查找)俱诸,對于Chrome DevTools不是很熟的同學(xué)菠劝,可以看下這個(gè)感覺挺全的;

以爬取螞蜂窩的游記為例睁搭,比如這一篇

1赶诊、通過request獲取網(wǎng)頁

request = urllib2.Request('http://www.mafengwo.cn/i/6958115.html')
response = urllib2.urlopen(request)
soup = BeautifulSoup(response.read().decode('utf8').encode('utf8'), "html.parser")

2、獲取標(biāo)題

return soup.select('.headtext')[0].string

3园骆、獲取文章html內(nèi)容

article = soup.select('.vc_article')[0]
html = article.prettify()

4舔痪、獲取用戶信息(如頭像,名稱),這個(gè)稍微要復(fù)雜一些锌唾,因?yàn)樗谏厦娴谝徊街苯诱埱蟮膆tml頁面里面是找不到的辙喂,然后通過Chrome DevTools中的Network功能,可以找到拉取這些信息的請求地址“https://www.mafengwo.cn/note/pagelet/pagelet/headOperateApi?callback=jQuery1810173556954190627_1492868085919&params=%7B%22iid%22%3A%226958115%22%7D&_=1492868086249”鸠珠,細(xì)心的你可能會發(fā)現(xiàn)巍耗,在這個(gè)請求中有個(gè)“6958115”,這個(gè)不就是第一步里面頁面的結(jié)尾數(shù)字嗎渐排,我們可以理解為id炬太;那么,這個(gè)請求就是通過

開始

https://www.mafengwo.cn/note/__pagelet__/pagelet/headOperateApi?callback=jQuery1810173556954190627_1492868085919&params=%7B%22iid%22%3A%226958115%22%7D&_=1492868086249](https://www.mafengwo.cn/note/__pagelet__/pagelet/headOperateApi?callback=jQuery1810173556954190627_1492868085919&params=%7B%22iid%22%3A%22

加上 id

6958115

加上結(jié)尾

%22%7D&_=1492868086249

最后組合成的一個(gè)完整的url驯耻,然后通過第一步請求后亲族,將獲取的數(shù)據(jù)通過正則的方式炒考,只去html部分,然后通過BeautifulSoup取出對應(yīng)的頭像霎迫,姓名斋枢;

//其中article_id就是上面說的第一步鏈接結(jié)尾數(shù)字“6958115”
userInfoURL = 'https://www.mafengwo.cn/note/__pagelet__/pagelet/headOperateApi?callback=jQuery1810173556954190627_1492868085919&params=%7B%22iid%22%3A%22' + article_id +'%22%7D&_=1492868086249'

request = urllib2.Request(userInfoURL)
response = urllib2.urlopen(request)
result = response.read()

pattern = re.compile('jQuery.*?\(')
pattern1 = re.compile('\)\;')

result = re.sub(pattern, "", result)
result = re.sub(pattern1, "", result)

result = eval(result)

html = result['data']['html']

soup = BeautifulSoup(html, "html.parser")

//頭像
avatar = soup.select('.per_pic img')[0]['src']

//用戶名
name = soup.select('.per_name')[0]['title'].encode('utf-8')

搭建服務(wù)器

在你爬取到數(shù)據(jù)之后,你總會希望能夠在界面上能夠真正的展示出來知给,所以瓤帚,我就決定使用python搭建一個(gè)簡單的本地服務(wù)器;因?yàn)橥ㄟ^學(xué)習(xí)python的時(shí)候發(fā)現(xiàn)菜鳥教程確實(shí)比較適合我這種菜鳥的涩赢,所以就看完了Django 菜鳥教程戈次,這個(gè)教程雖然簡單,但是全面筒扒,對我做一個(gè)簡單服務(wù)器來說怯邪,足夠了;然后花墩,就通過這個(gè)教程搭建了一個(gè)簡單的python服務(wù)器悬秉,在瀏覽器中,就可以看到自己爬取的頁面了冰蘑,具體可見整個(gè)項(xiàng)目代碼

mongodb 數(shù)據(jù)保存搂捧、使用

在你爬取一篇過后,肯定是不會停止的懂缕,所以,我們總會找個(gè)能夠保持我們爬取數(shù)據(jù)的地方(數(shù)據(jù)庫)王凑;因?yàn)橐郧霸谶M(jìn)行node開發(fā)的時(shí)候搪柑,使用過mongodb,所以就選擇了它作為我保存數(shù)據(jù)的地方索烹;使用python來操作mongodb工碾,我沒有找到相關(guān)比較好的文章,所以就直接參考的PyMongo 3.4.0 documentation這個(gè)api文檔百姓,這個(gè)夜比較詳細(xì)和簡單渊额,對于我來說夠用了;它包含了如何和mongodb鏈接垒拢、如何獲取數(shù)據(jù)庫旬迹,如何獲取數(shù)據(jù)庫里面的collection,如何查找求类、添加數(shù)據(jù)等等奔垦;其實(shí)很簡單:

from pymongo import MongoClient
import settings

#連接mongodb
client=MongoClient('mongodb://127.0.0.1:27017/')

//獲取數(shù)據(jù)庫
db = client[settings.DBNAME]

// 獲取數(shù)據(jù)庫里面的collection
def getCollection(collection):
    if(collection):
        return db[collection]
    else:
        return None 

數(shù)據(jù)保存的代碼就不貼出來了,有興趣可以看這個(gè)models.py.

自動爬取所有游記

當(dāng)你想爬取更多的時(shí)候尸疆,你肯定不希望是自己手動去查找一個(gè)一個(gè)的id椿猎,然后手動爬取惶岭,所以,我們就希望有更加自動化的爬取方式犯眠;對于這種方式按灶,必須得解決下面兩個(gè)問題:

  • 獲取所有的游記id(就形如“6958115”這種的東西)
  • 解決因?yàn)樽詣踊埱筮^快,過于頻繁筐咧,導(dǎo)致“服務(wù)器拒絕訪問”的問題

第一個(gè)鸯旁,獲取所有id;當(dāng)你使用Chrome DevTools Network去看列表下一頁的請求的時(shí)候嗜浮,你會發(fā)現(xiàn)羡亩,它訪問了一個(gè)“http://www.mafengwo.cn/note/pagelet/pagelet/recommendNoteApi?callback=jQuery18103478581123017468_1492999122522&params=%7B%22type%22%3A0%2C%22objid%22%3A0%2C%22page%22%3A1%2C%22ajax%22%3A1%2C%22retina%22%3A0%7D&_=1492999206862”這樣的鏈接,它也是和上面獲取用戶信息一樣分成三個(gè)部分危融,其中有個(gè)第幾頁的參數(shù)“page=1”,這里面就返回了所有的列表的html代碼畏铆,其中包括我們需要的id;

url = 'http://www.mafengwo.cn/note/__pagelet__/pagelet/recommendNoteApi?callback=jQuery18103478581123017468_1492999122522&params=%7B%22type%22%3A0%2C%22objid%22%3A0%2C%22page%22%3A'+str(page)+'%2C%22ajax%22%3A1%2C%22retina%22%3A0%7D&_=1492999206862'

request = urllib2.Request(url)
response = urllib2.urlopen(request)
result = response.read()

pattern = re.compile('jQuery.*?\(')
pattern1 = re.compile('\)\;')

result = re.sub(pattern, "", result)
result = re.sub(pattern1, "", result)
result = eval(result)

html = result['data']['html']
html = html.replace('\\/', '/')
html = html.decode('string-escape')
soup = BeautifulSoup(html, "html.parser")

links = soup.select('.tn-item .tn-image a')
_ids = []

for link in links:
    _id = link['href'].replace('/i/', '').replace('.html', '')
    _ids.append(_id)

然后我們就會根據(jù)每一頁獲取的id循環(huán)自動跑爬取對應(yīng)頁面數(shù)據(jù)并保存至數(shù)據(jù)庫吉殃,每跑完一頁的數(shù)據(jù)辞居,就會遞歸跑下一頁數(shù)據(jù),直到最后一頁

只是在跑的過程中蛋勺,就會遇到第二個(gè)問題瓦灶,因?yàn)樵L問過快、過于頻繁而導(dǎo)致服務(wù)器拒絕訪問抱完,在這兒我沒有通過網(wǎng)上說的各種高端的方式贼陶,而是采用的比較笨重的方式,就是在跑完一個(gè)請求后巧娱,讓程序休息幾秒鐘碉怔,再去進(jìn)行下一個(gè)請求,我將時(shí)間設(shè)置的10秒禁添,目前沒有拒絕訪問的問題撮胧,只是跑起來比較慢一些;

import time

.....
time.sleep(10)
.....

對于上面的所有代碼老翘,如果感興趣的芹啥,整個(gè)項(xiàng)目代碼可以在這兒(github)找到.

目前,爬取就差不多只有這些铺峭,后面會慢慢繼續(xù)去完善和學(xué)習(xí)潮剪;對于我來說敷硅,python的學(xué)習(xí)之路也才剛剛開始;

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市婚被,隨后出現(xiàn)的幾起案子屏鳍,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 222,627評論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件卧秘,死亡現(xiàn)場離奇詭異,居然都是意外死亡官扣,警方通過查閱死者的電腦和手機(jī)翅敌,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,180評論 3 399
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來惕蹄,“玉大人蚯涮,你說我怎么就攤上這事÷袅辏” “怎么了遭顶?”我有些...
    開封第一講書人閱讀 169,346評論 0 362
  • 文/不壞的土叔 我叫張陵,是天一觀的道長泪蔫。 經(jīng)常有香客問我棒旗,道長,這世上最難降的妖魔是什么撩荣? 我笑而不...
    開封第一講書人閱讀 60,097評論 1 300
  • 正文 為了忘掉前任铣揉,我火速辦了婚禮,結(jié)果婚禮上餐曹,老公的妹妹穿的比我還像新娘逛拱。我一直安慰自己,他們只是感情好台猴,可當(dāng)我...
    茶點(diǎn)故事閱讀 69,100評論 6 398
  • 文/花漫 我一把揭開白布朽合。 她就那樣靜靜地躺著,像睡著了一般饱狂。 火紅的嫁衣襯著肌膚如雪曹步。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,696評論 1 312
  • 那天嗡官,我揣著相機(jī)與錄音,去河邊找鬼毯焕。 笑死衍腥,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的纳猫。 我是一名探鬼主播婆咸,決...
    沈念sama閱讀 41,165評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼芜辕!你這毒婦竟也來了尚骄?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 40,108評論 0 277
  • 序言:老撾萬榮一對情侶失蹤侵续,失蹤者是張志新(化名)和其女友劉穎倔丈,沒想到半個(gè)月后憨闰,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,646評論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡需五,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,709評論 3 342
  • 正文 我和宋清朗相戀三年鹉动,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片宏邮。...
    茶點(diǎn)故事閱讀 40,861評論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡泽示,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出蜜氨,到底是詐尸還是另有隱情械筛,我是刑警寧澤,帶...
    沈念sama閱讀 36,527評論 5 351
  • 正文 年R本政府宣布飒炎,位于F島的核電站埋哟,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏厌丑。R本人自食惡果不足惜定欧,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,196評論 3 336
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望怒竿。 院中可真熱鬧砍鸠,春花似錦、人聲如沸耕驰。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,698評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽朦肘。三九已至饭弓,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間媒抠,已是汗流浹背弟断。 一陣腳步聲響...
    開封第一講書人閱讀 33,804評論 1 274
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留趴生,地道東北人阀趴。 一個(gè)月前我還...
    沈念sama閱讀 49,287評論 3 379
  • 正文 我出身青樓,卻偏偏與公主長得像苍匆,于是被迫代替她去往敵國和親刘急。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,860評論 2 361

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

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,325評論 25 707
  • 聲明:本文講解的實(shí)戰(zhàn)內(nèi)容浸踩,均僅用于學(xué)習(xí)交流叔汁,請勿用于任何商業(yè)用途! 一、前言 強(qiáng)烈建議:請?jiān)陔娔X的陪同下据块,閱讀本文...
    Bruce_Szh閱讀 12,725評論 6 28
  • 我叔叔來信了码邻,說是找我借錢? 他這么有錢瑰钮,一個(gè)大商人冒滩,都快進(jìn)福布斯排行榜的人,找我借錢浪谴?難道是破產(chǎn)了开睡? 他說的很明...
    予墨讀書閱讀 109評論 0 0
  • 走出一身汗 回家 越來越喜歡流汗的感覺 朋友小聚完 繼續(xù)走壩 此時(shí) 沒有什么人 除了一兩對黑暗中緊擁的情侶 除了一...
    撞墻的豆腐閱讀 382評論 0 0
  • 那一潭洶涌的真心實(shí)意, 在念念不忘中丟了執(zhí)著苟耻, 曾經(jīng)相融進(jìn)生命的風(fēng)景篇恒, 在人來人往中淡了視線, 捧起的流沙散落了凶杖,...
    蛋蛋妮兒閱讀 411評論 0 0