Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537 Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537
要:從零開始寫爬蟲,初學(xué)者的速成指南!
需要免費(fèi)獲取本文章講解的視頻+源碼,關(guān)注+轉(zhuǎn)發(fā)此文然后私信我回復(fù)“音樂(lè)”即可領(lǐng)取資料,也歡迎大家和我一起交流學(xué)習(xí)Python,共同成長(zhǎng)
封面:
封面
大家好,《手把手教你寫網(wǎng)絡(luò)爬蟲》連載開始了!在筆者的職業(yè)生涯中,幾乎沒(méi)有發(fā)現(xiàn)像網(wǎng)絡(luò)爬蟲這樣的編程實(shí)踐,可以同時(shí)吸引程序員和門外漢的注意。本文由淺入深的把爬蟲技術(shù)和盤托出,為初學(xué)者提供一種輕松的入門方式。請(qǐng)跟隨我們一起踏上爬蟲學(xué)習(xí)的打怪升級(jí)之路吧!
介紹
什么是爬蟲?
先看看百度百科的定義:
網(wǎng)絡(luò)爬蟲
簡(jiǎn)單的說(shuō)網(wǎng)絡(luò)爬蟲(Web crawler)也叫做網(wǎng)絡(luò)鏟(Web scraper)、網(wǎng)絡(luò)蜘蛛(Web spider),其行為一般是先“爬”到對(duì)應(yīng)的網(wǎng)頁(yè)上,再把需要的信息“鏟”下來(lái)。
為什么學(xué)習(xí)爬蟲?
看到這里,有人就要問(wèn)了:google、百度等搜索引擎已經(jīng)幫我們抓取了互聯(lián)網(wǎng)上的大部分信息了,為什么還要自己寫爬蟲呢?這是因?yàn)椋枨笫嵌鄻拥摹1热缭谄髽I(yè)中,爬取下來(lái)的數(shù)據(jù)可以作為數(shù)據(jù)挖掘的數(shù)據(jù)源。甚至有人為了炒股,專門抓取股票信息。筆者就見過(guò)有人為了分析房?jī)r(jià),自學(xué)編程,爬了綠中介的數(shù)據(jù)。
在大數(shù)據(jù)深入人心的時(shí)代,網(wǎng)絡(luò)爬蟲作為網(wǎng)絡(luò)、存儲(chǔ)與機(jī)器學(xué)習(xí)等領(lǐng)域的交匯點(diǎn),已經(jīng)成為滿足個(gè)性化網(wǎng)絡(luò)數(shù)據(jù)需求的最佳實(shí)踐。還猶豫什么?讓我們開始學(xué)習(xí)吧!
語(yǔ)言&環(huán)境
語(yǔ)言:人生苦短,我用Python。讓Python帶我們飛!
Python
urllib.request:這是Python自帶的庫(kù),不需要單獨(dú)安裝,它的作用是為我們打開url獲取html的內(nèi)容。Python官方文檔的介紹:The urllib.request module defines functions and classes which help in opening URLs (mostly HTTP) in a complex world — basic and digest authentication, redirections, cookies and more.
BeautifulSoup:是一個(gè)可以從HTML或XML文件中提取數(shù)據(jù)的Python庫(kù)。它能夠通過(guò)你喜歡的轉(zhuǎn)換器實(shí)現(xiàn)慣用的文檔導(dǎo)航,查找,修改文檔的方式。Beautiful Soup會(huì)幫你節(jié)省數(shù)小時(shí)甚至數(shù)天的工作時(shí)間。安裝比較簡(jiǎn)單:
$pip install beautifulsoup4
驗(yàn)證的方法,進(jìn)入Python直接import一下,如果沒(méi)有異常,那就說(shuō)明安裝成功了!
BeautifulSoup
“美味的湯,綠色的濃湯,
在熱氣騰騰的蓋碗里裝!
誰(shuí)不愿意嘗一嘗,這樣的好湯?
晚餐用的湯,美味的湯!”
BeautifulSoup庫(kù)的名字取自《愛(ài)麗絲夢(mèng)游仙境》里的同名詩(shī)歌。
爬取數(shù)據(jù)
接下來(lái),我們就用urllib.request獲取html內(nèi)容,再用BeautifulSoup提取其中的數(shù)據(jù),完成一次簡(jiǎn)單的爬取。
urllib.request
把這段代碼保存為get_html.py,然后運(yùn)行,看看輸出了什么:
get_html.py
果然,輸出了http://jr.jd.com 這個(gè)網(wǎng)頁(yè)的全部HTML代碼。
輸出的代碼簡(jiǎn)直無(wú)法直視,如何方便的找到我們想抓取數(shù)據(jù)呢?用Chrome打開url,然后按F12,再按Ctrl + Shift + C。如果我們要抓導(dǎo)航欄,就用鼠標(biāo)點(diǎn)擊任意一個(gè)導(dǎo)航欄的項(xiàng)目,瀏覽器就在html中找到了它的位置。效果如下:
HTML代碼
定位到的html代碼:
html代碼
有了這些信息,就可以用BeautifulSoup提取數(shù)據(jù)了。升級(jí)一下代碼:
BeautifulSoup
把這段代碼保存為get_data.py,然后運(yùn)行,看看輸出了什么:
get_data.py
沒(méi)錯(cuò),得到了我們想要的數(shù)據(jù)!
BeautifulSoup提供一些簡(jiǎn)單的、Python式的函數(shù)用來(lái)處理導(dǎo)航、搜索、修改分析樹等功能。它是一個(gè)工具箱,通過(guò)解析文檔為用戶提供需要抓取的數(shù)據(jù),因?yàn)楹?jiǎn)單,所以不需要多少代碼就可以寫出一個(gè)完整的應(yīng)用程序。怎么樣,是不是覺(jué)得只要復(fù)制粘貼就可以寫爬蟲了?簡(jiǎn)單的爬蟲確實(shí)是可以的!
一個(gè)迷你爬蟲
我們先定一個(gè)小目標(biāo):爬取網(wǎng)易云音樂(lè)播放數(shù)大于500萬(wàn)的歌單。
打開歌單的url: http://music.163.com/#/discover/playlist,然后用BeautifulSoup提取播放數(shù)<span class="nb">3715</span>。結(jié)果表明,我們什么也沒(méi)提取到。難道我們打開了一個(gè)假的網(wǎng)頁(yè)?
動(dòng)態(tài)網(wǎng)頁(yè):所謂的動(dòng)態(tài)網(wǎng)頁(yè),是指跟靜態(tài)網(wǎng)頁(yè)相對(duì)的一種網(wǎng)頁(yè)編程技術(shù)。靜態(tài)網(wǎng)頁(yè),隨著html代碼的生成,頁(yè)面的內(nèi)容和顯示效果就基本上不會(huì)發(fā)生變化了——除非你修改頁(yè)面代碼。而動(dòng)態(tài)網(wǎng)頁(yè)則不然,頁(yè)面代碼雖然沒(méi)有變,但是顯示的內(nèi)容卻是可以隨著時(shí)間、環(huán)境或者數(shù)據(jù)庫(kù)操作的結(jié)果而發(fā)生改變的。
值得強(qiáng)調(diào)的是,不要將動(dòng)態(tài)網(wǎng)頁(yè)和頁(yè)面內(nèi)容是否有動(dòng)感混為一談。這里說(shuō)的動(dòng)態(tài)網(wǎng)頁(yè),與網(wǎng)頁(yè)上的各種動(dòng)畫、滾動(dòng)字幕等視覺(jué)上的動(dòng)態(tài)效果沒(méi)有直接關(guān)系,動(dòng)態(tài)網(wǎng)頁(yè)也可以是純文字內(nèi)容的,也可以是包含各種動(dòng)畫的內(nèi)容,這些只是網(wǎng)頁(yè)具體內(nèi)容的表現(xiàn)形式,無(wú)論網(wǎng)頁(yè)是否具有動(dòng)態(tài)效果,只要是采用了動(dòng)態(tài)網(wǎng)站技術(shù)生成的網(wǎng)頁(yè)都可以稱為動(dòng)態(tài)網(wǎng)頁(yè)。
現(xiàn)在我們明白了,這是一個(gè)動(dòng)態(tài)網(wǎng)頁(yè),我們得到它的時(shí)候,歌單還沒(méi)請(qǐng)求到呢,當(dāng)然什么都提取不出來(lái)!
我們之前的技術(shù)不能執(zhí)行那些讓頁(yè)面產(chǎn)生各種神奇效果的JavaScript 代碼。如果網(wǎng)站的HTML頁(yè)面沒(méi)有運(yùn)行JavaScript,就可能和你在瀏覽器里看到的樣子完全不同,因?yàn)闉g覽器可以正確地執(zhí)行JavaScript。用Python 解決這個(gè)問(wèn)題只有兩種途徑:直接從JavaScript 代碼里采集內(nèi)容,或者用Python 的第三方庫(kù)運(yùn)行JavaScript,直接采集你在瀏覽器里看到的頁(yè)面。我們當(dāng)然選擇后者。今天第一課,不深究原理,先簡(jiǎn)單粗暴的實(shí)現(xiàn)我們的小目標(biāo)。
干
Selenium:是一個(gè)強(qiáng)大的網(wǎng)絡(luò)數(shù)據(jù)采集工具,其最初是為網(wǎng)站自動(dòng)化測(cè)試而開發(fā)的。近幾年,它還被廣泛用于獲取精確的網(wǎng)站快照,因?yàn)樗鼈兛梢灾苯舆\(yùn)行在瀏覽器上。Selenium 庫(kù)是一個(gè)在WebDriver 上調(diào)用的API。WebDriver 有點(diǎn)兒像可以加載網(wǎng)站的瀏覽器,但是它也可以像BeautifulSoup對(duì)象一樣用來(lái)查找頁(yè)面元素,與頁(yè)面上的元素進(jìn)行交互(發(fā)送文本、點(diǎn)擊等),以及執(zhí)行其他動(dòng)作來(lái)運(yùn)行網(wǎng)絡(luò)爬蟲。安裝方式與其他Python第三方庫(kù)一樣。
$pip install Selenium
驗(yàn)證一下:
Selenium
Selenium 自己不帶瀏覽器,它需要與第三方瀏覽器結(jié)合在一起使用。例如,如果你在Firefox 上運(yùn)行Selenium,可以直接看到一個(gè)Firefox 窗口被打開,進(jìn)入網(wǎng)站,然后執(zhí)行你在代碼中設(shè)置的動(dòng)作。雖然這樣可以看得更清楚,但不適用于我們的爬蟲程序,爬一頁(yè)就打開一頁(yè)效率太低,所以我們用一個(gè)叫PhantomJS的工具代替真實(shí)的瀏覽器。
PhantomJS:是一個(gè)“無(wú)頭”(headless)瀏覽器。它會(huì)把網(wǎng)站加載到內(nèi)存并執(zhí)行頁(yè)面上的JavaScript,但是它不會(huì)向用戶展示網(wǎng)頁(yè)的圖形界面。把Selenium和PhantomJS 結(jié)合在一起,就可以運(yùn)行一個(gè)非常強(qiáng)大的網(wǎng)絡(luò)爬蟲了,可以處理cookie、JavaScript、header,以及任何你需要做的事情。
PhantomJS并不是Python的第三方庫(kù),不能用pip安裝。它是一個(gè)完善的瀏覽器,所以你需要去它的官方網(wǎng)站下載,然后把可執(zhí)行文件拷貝到Python安裝目錄的Scripts文件夾,像這樣:
Scripts文件夾
開始干活!
打開歌單的第一頁(yè):
http://music.163.com/#/discover/playlist/?order=hot&cat=%E5%85%A8%E9%83%A8&limit=35&offset=0
用Chrome的“開發(fā)者工具”F12先分析一下,很容易就看穿了一切。
html代碼
播放數(shù)nb (number broadcast):29915
封面 msk (mask):有標(biāo)題和url
同理,可以找到“下一頁(yè)”的url,最后一頁(yè)的url是“javascript:void(0)”。
最后,用18行代碼即可完成我們的工作。
代碼
把這段代碼保存為get_data.py,然后運(yùn)行。運(yùn)行結(jié)束后,在程序的目錄里生成了一個(gè)playlist.csv文件。
playlist.csv文件
看到成果后是不是很有成就感?如果你感興趣,還可以按照這個(gè)思路,找找評(píng)論數(shù)最多的單曲,再也不用擔(dān)心沒(méi)歌聽了!
需要免費(fèi)獲取本文章講解的視頻+源碼,關(guān)注+轉(zhuǎn)發(fā)此文然后私信我回復(fù)“音樂(lè)”即可領(lǐng)取資料,也歡迎大家和我一起交流學(xué)習(xí)Python,共同成長(zhǎng)
今天的內(nèi)容比較淺顯,希望對(duì)你有用。就先介紹到這里,我們下期再見!
身、吃飯、敲代碼;等車、擼貓、下午茶……若能佐以合適的音樂(lè)當(dāng)“配餐”,總是愜意非常。本文就將帶你爬一爬網(wǎng)易云的那些熱門歌單!
作者 | 上海小胖
責(zé)編 | 仲培藝
心情好或心情壞,點(diǎn)一首歌撫慰你受傷或躁動(dòng)的心靈——下面教你用 15 行代碼搞定熱門歌單!
本文使用的是 Selenium 模塊,它是一個(gè)自動(dòng)化測(cè)試工具,利用它我們可以驅(qū)動(dòng)瀏覽器執(zhí)行特定的動(dòng)作,如點(diǎn)擊、下拉等操作,對(duì)于一些 JavaScript 渲染的頁(yè)面來(lái)說(shuō),此種抓取方式非常有效。
采用了 Chrome 瀏覽器配合 Selenium 工作,本文的 Python 版本是 3.7.2。
準(zhǔn)備工作
1. 若你的環(huán)境中沒(méi)有 Selenium 模塊,直接使用 pip 安裝即可:
pip install selenium
2. 打開谷歌瀏覽器,檢查Chrome的版本:在瀏覽器地址中輸入 chrome://settings/help 回車即可看到:
3. 打開 ChromeDriver 的官方網(wǎng)站(https://sites.google.com/a/chromium.org/chromedriver/downloads),尋找與你當(dāng)前瀏覽器版本相對(duì)應(yīng)的 ChromeDriver 下載:
4. 選擇你自己的操作系統(tǒng)類型進(jìn)行下載即可:
5. 以 Windows 為例,下載結(jié)束后,將 ChromeDriver 放置在 Python 安裝目錄下的 Scripts 文件夾即可:
準(zhǔn)備工作完成,代碼寫起來(lái)吧~
迷你爬蟲的實(shí)現(xiàn)
我們這次的目標(biāo)是爬取熱門歌單,比如網(wǎng)易云音樂(lè)中播放量大于 1000萬(wàn) 的歌單信息(歌單名稱、鏈接)。
1. 先來(lái)打開網(wǎng)易云的歌單第一頁(yè):
https://music.163.com/#/discover/playlist/
2. 使用 Chrome 的開發(fā)者工具 <F12> 進(jìn)行分析:
我們想要拿的信息全在這里:
msk,封面 [mask]:有歌單的名稱及鏈接
nb,播放數(shù) [number broadcast]:135萬(wàn)
3. 我們還需要遍歷所有的頁(yè),使用工具繼續(xù)分析,找到“下一頁(yè)”的 URL:
4. 切換至最后一頁(yè),拿到最后一頁(yè)的 URL:
5. 等我們爬取完所有符合的歌單信息后,將其保存在本地;
6.全部工作結(jié)束,最后再通過(guò)下面的偽代碼回顧下整體思路:
7. 爬取的效果如下:
另附源碼:https://github.com/MiracleYoung/You-are-Pythonista/tree/master/PythonExercise/Tool/Mini_Crawl
作者簡(jiǎn)介:上海小胖,四大咨詢的TechLead,mongoDB Professional 獲得者。「Python專欄」專注Python領(lǐng)域的各種技術(shù):爬蟲、DevOps、人工智能、Web開發(fā)等。
本文系作者投稿,版權(quán)歸作者所有。
這個(gè)星期我的個(gè)人項(xiàng)目——(能導(dǎo)入各個(gè)平臺(tái)歌單的)音樂(lè)播放器已經(jīng)開始啦。所以先理清思路:
期間可能會(huì)遇到各種問(wèn)題或者說(shuō)我的思路有問(wèn)題的地方會(huì)進(jìn)行改進(jìn),當(dāng)然同時(shí)也不吝賜教。
一、selenium模擬登陸
首先是安裝并且配置selenium的環(huán)境,網(wǎng)上都有教程這里就不贅述了。
接著進(jìn)行網(wǎng)頁(yè)的分析,打開網(wǎng)易云界面,我們首先要實(shí)現(xiàn)模擬登陸的功能。
查看此處的代碼結(jié)構(gòu):
點(diǎn)擊后彈出新的框:
此處因?yàn)樾枰c(diǎn)擊QQ登錄因此利用css選擇器使用下列代碼:
from selenium import webdriver from selenium.webdriver.chrome.options import Options from selenium.webdriver.common.keys import Keys from time import sleep class getMusic(): #chrome_options=Options() #設(shè)置為無(wú)界面模式 #chrome_options.add_argument('--headless') userid='***' #這里填上QQ號(hào) password='***'#這里填上對(duì)應(yīng)的密碼 browser = webdriver.Chrome() browser.implicitly_wait(10) browser.get("https://music.163.com/") #login = browser.find_element_by_link_text('登錄') #login.click() browser.implicitly_wait(10) browser.find_element_by_css_selector(".m-tophead.f-pr.j-tflag > a").click() #點(diǎn)擊登錄 #css 選擇器中如果一個(gè) tag 的 class 包含空格,要用.號(hào)代替空格 browser.find_element_by_css_selector(".lyct.lyct-1 > div > div.u-alt > ul > li:nth-child(2) > a").click() #點(diǎn)擊QQ登錄
運(yùn)行代碼,進(jìn)入下列界面:
我們要先對(duì)選項(xiàng)卡進(jìn)行切換
music_handle = browser.current_window_handle print(music_handle) # 輸出當(dāng)前窗口句柄 handles = browser.window_handles # 獲取當(dāng)前全部窗口句柄集合 print(handles) #切換到QQ登陸頁(yè)面 for handle in handles: if handle != browser.current_window_handle: print('switch to qq login window') browser.switch_to.window(handle) browser.implicitly_wait(10) ##QQlogin = browser.find_element_by_link_text('QQ登錄') #QQlogin.click() #music_handle = browser.current_window_handle browser.implicitly_wait(10) sleep(2)
接著我們發(fā)現(xiàn)QQ登錄窗口含有iframe:
因此先切換此窗口:
browser.switch_to.frame('ptlogin_iframe')
再點(diǎn)擊帳號(hào)密碼登錄,出現(xiàn)文本框?qū)①~號(hào)密碼輸入后進(jìn)行登錄。
browser.find_element_by_link_text('帳號(hào)密碼登錄').click() userid_ele=browser.find_element_by_name('u') #password_ele=browser.find_element_by_id('pwdArea') password_ele=browser.find_element_by_name('p') userid_ele.send_keys(userid) password_ele.send_keys(password) browser.find_element_by_id('login_button').click()
切換回原窗口:
browser.switch_to.window(music_handle)
完成登錄:
二、初步獲得歌單信息
首先進(jìn)入我的音樂(lè):
代碼:
browser.find_element_by_xpath('//*[@id="g-topbar"]/div[1]/div/ul/li[2]/span/a/em').click() browser.implicitly_wait(10) sleep(2)
接下來(lái)提取歌單的名稱:
經(jīng)過(guò)檢查代碼發(fā)現(xiàn),這里也是個(gè)iframe:
browser.switch_to.frame('contentFrame')
提取名稱:
list=[] #list=browser.find_element_by_xpath('//*[@id="g_mymusic"]/div/div[1]/div/div[1]/ul/li[3]') #list.click() i=1 while True: try: list=browser.find_element_by_xpath('//*[@id="g_mymusic"]/div/div[1]/div/div[1]/ul/li[{}]'.format(i)) print(list.text) i=i+1 except: print('over') break;
輸出結(jié)果:
?
(未完待續(xù),如以上有疑問(wèn),不吝賜教)
*請(qǐng)認(rèn)真填寫需求信息,我們會(huì)在24小時(shí)內(nèi)與您取得聯(lián)系。