Python采集CSDN博客排行榜数据
文章目錄
- 前言
- 網(wǎng)絡(luò)爬蟲(chóng)
- 搜索引擎
- 爬蟲(chóng)應(yīng)用
- 謹(jǐn)防違法
- 爬蟲(chóng)實(shí)戰(zhàn)
- 網(wǎng)頁(yè)分析
- 編寫(xiě)代碼
- 運(yùn)行效果
- 反爬技術(shù)
很多人學(xué)習(xí)python,不知道從何學(xué)起。
很多人學(xué)習(xí)python,掌握了基本語(yǔ)法過(guò)后,不知道在哪里尋找案例上手。
很多已經(jīng)做案例的人,卻不知道如何去學(xué)習(xí)更加高深的知識(shí)。
那么針對(duì)這三類(lèi)人,我給大家提供一個(gè)好的學(xué)習(xí)平臺(tái),免費(fèi)領(lǐng)取視頻教程,電子書(shū)籍,以及課程的源代碼!
QQ群:101677771
前言
開(kāi)始接觸 CTF 網(wǎng)絡(luò)安全比賽發(fā)現(xiàn)不會(huì)寫(xiě) Python 腳本的話(huà)簡(jiǎn)直寸步難行……故丟棄 Java 學(xué)習(xí)下 Python 語(yǔ)言,但單純學(xué)習(xí)語(yǔ)法又覺(jué)得枯燥……所以從 Python 爬蟲(chóng)應(yīng)用實(shí)戰(zhàn)入手進(jìn)行學(xué)習(xí) Python。本文將簡(jiǎn)述爬蟲(chóng)定義、爬蟲(chóng)基礎(chǔ)、反爬技術(shù) 和 CSDN博客排行榜數(shù)據(jù)爬取實(shí)戰(zhàn)。
網(wǎng)絡(luò)爬蟲(chóng)
網(wǎng)絡(luò)爬蟲(chóng)又稱(chēng)網(wǎng)絡(luò)蜘蛛、網(wǎng)絡(luò)螞蟻、網(wǎng)絡(luò)機(jī)器人等,可以代替人們自動(dòng)地在互聯(lián)網(wǎng)中進(jìn)行數(shù)據(jù)信息的采集與整理。在大數(shù)據(jù)時(shí)代,信息的采集是一項(xiàng)重要的工作,如果單純靠人力進(jìn)行信息采集,不僅低效繁瑣,搜集的成本也會(huì)提高。
網(wǎng)絡(luò)爬蟲(chóng)自動(dòng)化瀏覽網(wǎng)絡(luò)中的信息的時(shí)候需要按照我們制定的規(guī)則進(jìn)行,這些規(guī)則我們稱(chēng)之為網(wǎng)絡(luò)爬蟲(chóng)算法。使用Python可以很方便地編寫(xiě)出爬蟲(chóng)程序,進(jìn)行互聯(lián)網(wǎng)信息的自動(dòng)化檢索。
搜索引擎
搜索引擎離不開(kāi)爬蟲(chóng),比如百度搜索引擎的爬蟲(chóng)叫作百度蜘蛛(Baiduspider)。百度蜘蛛每天會(huì)在海量的互聯(lián)網(wǎng)信息中進(jìn)行爬取,爬取優(yōu)質(zhì)信息并收錄,當(dāng)用戶(hù)在百度搜索引擎上檢索對(duì)應(yīng)關(guān)鍵詞時(shí),百度將對(duì)關(guān)鍵詞進(jìn)行分析處理,從收錄的網(wǎng)頁(yè)中找出相關(guān)網(wǎng)頁(yè),按照一定的排名規(guī)則進(jìn)行排序并將結(jié)果展現(xiàn)給用戶(hù)。(除了百度搜索引擎離不開(kāi)爬蟲(chóng)以外,其他搜索引擎也離不開(kāi)爬蟲(chóng),它們也擁有自己的爬蟲(chóng)。比如360的爬蟲(chóng)叫360Spider,搜狗的爬蟲(chóng)叫Sogouspider,必應(yīng)的爬蟲(chóng)叫Bingbot。)
在這個(gè)過(guò)程中,百度蜘蛛起到了至關(guān)重要的作用。那么,如何覆蓋互聯(lián)網(wǎng)中更多的優(yōu)質(zhì)網(wǎng)頁(yè)?又如何篩選這些重復(fù)的頁(yè)面?這些都是由百度蜘蛛爬蟲(chóng)的算法決定的。采用不同的算法,爬蟲(chóng)的運(yùn)行效率會(huì)不同,爬取結(jié)果也會(huì)有所差異。所以,我們?cè)谘芯颗老x(chóng)的時(shí)候,不僅要了解爬蟲(chóng)如何實(shí)現(xiàn),還需要知道一些常見(jiàn)爬蟲(chóng)的算法,如果有必要,我們還需要自己去制定相應(yīng)的算法,在此,我們僅需要對(duì)爬蟲(chóng)的概念有一個(gè)基本的了解。
爬蟲(chóng)應(yīng)用
在上面的圖中可以看到,網(wǎng)絡(luò)爬蟲(chóng)可以代替手工做很多事情,比如可以用于做搜索引擎,也可以爬取網(wǎng)站上面的圖片,比如有些朋友將某些網(wǎng)站上的圖片全部爬取下來(lái),集中進(jìn)行瀏覽,同時(shí),網(wǎng)絡(luò)爬蟲(chóng)也可以用于金融投資領(lǐng)域,比如可以自動(dòng)爬取一些金融信息,并進(jìn)行投資分析等。
由于互聯(lián)網(wǎng)中的用戶(hù)數(shù)據(jù)信息,相對(duì)來(lái)說(shuō)是比較敏感的數(shù)據(jù)信息,所以,用戶(hù)爬蟲(chóng)的利用價(jià)值也相對(duì)較高。利用用戶(hù)爬蟲(chóng)可以做大量的事情,比如在2015年,有網(wǎng)友爬取了3000萬(wàn)QQ空間的用戶(hù)信息,并同樣從中獲得了大量潛在數(shù)據(jù):
- QQ空間用戶(hù)發(fā)說(shuō)說(shuō)的時(shí)間規(guī)律:晚上22點(diǎn)左右,平均發(fā)說(shuō)說(shuō)的數(shù)量是一天中最多的時(shí)候;
- QQ空間用戶(hù)的年齡階段分布:出生于1990年到1995年的用戶(hù)相對(duì)來(lái)說(shuō)較多;
- QQ空間用戶(hù)的性別分布:男生占比多于50%,女生占比多于30%,未填性別的占10%左右。
用戶(hù)爬蟲(chóng)還可以做很多事情,比如爬取淘寶的用戶(hù)信息,可以分析淘寶用戶(hù)喜歡什么商品,從而更有利于我們對(duì)商品的定位等。由此可見(jiàn),利用用戶(hù)爬蟲(chóng)可以獲得很多有趣的潛在信息。
謹(jǐn)防違法
網(wǎng)絡(luò)爬蟲(chóng)在大多數(shù)情況中都不違法,我們生活中幾乎每天都在爬蟲(chóng)應(yīng)用(如百度),從目前的情況來(lái)看,如果抓取的數(shù)據(jù)屬于個(gè)人使用或科研范疇,基本不存在問(wèn)題;而如果數(shù)據(jù)屬于商業(yè)盈利范疇,就有可能屬于違法行為。
Robots協(xié)議
Robots協(xié)議(爬蟲(chóng)協(xié)議)的全稱(chēng)是“網(wǎng)絡(luò)爬蟲(chóng)排除標(biāo)準(zhǔn)”(Robots Exclusion Protocol),網(wǎng)站通過(guò)Robots協(xié)議告訴搜索引擎哪些頁(yè)面可以抓取,哪些頁(yè)面不能抓取。該協(xié)議是國(guó)際互聯(lián)網(wǎng)界通行的道德規(guī)范,雖然沒(méi)有寫(xiě)入法律,但是每一個(gè)爬蟲(chóng)都應(yīng)該遵守這項(xiàng)協(xié)議。
淘寶網(wǎng)對(duì)用戶(hù)代理為百度爬蟲(chóng)引擎進(jìn)行了規(guī)定,我們可以查看淘寶網(wǎng)的 robots.txt:
最后一行,Disallow:/?表示禁止百度爬蟲(chóng)訪(fǎng)問(wèn)除了Allow規(guī)定頁(yè)面外的其他所有頁(yè)面。百度作為一個(gè)搜索引擎,良好地遵守了淘寶網(wǎng)的 robot.txt 協(xié)議。
網(wǎng)絡(luò)爬蟲(chóng)的約束
除了上述Robots協(xié)議之外,我們使用網(wǎng)絡(luò)爬蟲(chóng)的時(shí)候還要對(duì)自己進(jìn)行約束:過(guò)于快速或者頻密的網(wǎng)絡(luò)爬蟲(chóng)都會(huì)對(duì)服務(wù)器產(chǎn)生巨大的壓力,網(wǎng)站可能封鎖你的IP,甚至采取進(jìn)一步的法律行動(dòng)。因此,你需要約束自己的網(wǎng)絡(luò)爬蟲(chóng)行為,將請(qǐng)求的速度限定在一個(gè)合理的范圍之內(nèi)。簡(jiǎn)而言之,如果你因?yàn)榕廊?shù)據(jù)導(dǎo)致人家服務(wù)器宕機(jī),你就惹禍上身了……
爬蟲(chóng)實(shí)戰(zhàn)
進(jìn)入正題之前通過(guò)一張圖來(lái)簡(jiǎn)要了解下爬蟲(chóng)的工作過(guò)程:
下面將演示如何借助 Python 爬蟲(chóng)爬取CSDN排行榜Top 100的大佬們的數(shù)據(jù)信息,保存到本地 Excel 文件進(jìn)行膜拜。
網(wǎng)頁(yè)分析
訪(fǎng)問(wèn)本次爬取目標(biāo)——CSDN博客排行榜:https://blog.csdn.net/rank/writing_rank:
抓包分析:
發(fā)現(xiàn)返回排行榜用戶(hù)信息(每次返回一頁(yè)10位)的API:
- 1
具體數(shù)據(jù)包如下:
分析一下參數(shù):
編寫(xiě)代碼
1、初始化參數(shù):
def __init__(self):self.ua = UserAgent().chromeself.url = 'https://blog.csdn.net/api/WritingRank/weekList?' # ajax 請(qǐng)求網(wǎng)址self.header = {'Referer': 'https://blog.csdn.net/weixin_39190897',"Upgrade-Insecure-Requests": "1",'User-Agent': self.ua}# 配置保存表格的基本self.workbook = Workbook()self.sheet = self.workbook.activeself.sheet.title = 'CSDNTop100信息'self.sheet['A1'] = '排名'self.sheet['B1'] = '用戶(hù)名'self.sheet['C1'] = '用戶(hù)頭像'self.sheet['D1'] = '用戶(hù)博客網(wǎng)址'self.sheet['E1'] = '粉絲數(shù)'self.sheet['F1'] = '點(diǎn)贊數(shù)'self.sheet['G1'] = '上周排名'self.sheet['H1'] = '博客等級(jí)'self.sheet['I1'] = '排名時(shí)間'def __params(self, offset):self.offset = offset"""構(gòu)造請(qǐng)求參數(shù)"""self.params = {"username": "weixin_39190897","page": str(self.offset),"size": "10"}2、爬取網(wǎng)址:
def spider(self):"""構(gòu)造 多頁(yè) 爬取"""for i in range(1, 11):self.__params(i)url = self.url + urlencode(self.params)r = requests.get(url, headers=self.header)if r.status_code == 200:r.encoding = r.apparent_encodingyield r.json()else:print('[info] request error ! the status_code is ' + r.status_code)time.sleep(0.5)3、分析json包:
def parse_json(self, r_json):"""根據(jù)網(wǎng)站請(qǐng)求返回的json包 進(jìn)行進(jìn)一步分析"""# 第一層first_data = r_json.get('data')if first_data:# 第二層list_data = first_data.get('list')if list_data: # 判空f(shuō)or i in list_data:rank = i.get("ranking")head_image = i.get('avatar')user_nickname = i.get('user_nickname') # 用戶(hù)名username = i.get('username') # 用戶(hù)idfans_num = i.get('fans_num') # 粉絲fav_num = i.get('fav_num') # 獲贊last_rank = i.get('last_ranking') # 上周排名leave = i.get('profile_level').get('level') # 博客等級(jí)if rank and head_image and user_nickname and user_nickname and username and fans_num \and fav_num and last_rank and leave:# 這里保存數(shù)據(jù) 只是為了方便轉(zhuǎn)換其他保存格式 僅僅是保存excel中用到列表yield {'rank': rank,'user_nickname': user_nickname,'head_image': head_image,'username': 'https://blog.csdn.net/' + username,'fans_num': fans_num,'fav_num': fav_num,'last_rank': last_rank,'leave': leave}4、下載保存excel表格
def down(self, item):"""保存至excel表格"""now_time = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime()) # 時(shí)間leave_list = []for value in item.values():leave_list.append(value)leave_list.append(now_time)self.sheet.append(leave_list)5、完整腳本:
# -*- coding : utf-8 -*- import requests from urllib.parse import urlencode from fake_useragent import UserAgent import time from openpyxl import Workbookclass CSDNSpider(object):"""爬取csdn top 100 的各種信息url = 'https://blog.csdn.net/rank/writing_rank'ajax方式"""def __init__(self):self.ua = UserAgent().chromeself.url = 'https://blog.csdn.net/api/WritingRank/weekList?' # ajax 請(qǐng)求網(wǎng)址self.header = {'Referer': 'https://blog.csdn.net/weixin_39190897',"Upgrade-Insecure-Requests": "1",'User-Agent': self.ua}# 配置保存表格的基本self.workbook = Workbook()self.sheet = self.workbook.activeself.sheet.title = 'CSDNTop100信息'self.sheet['A1'] = '排名'self.sheet['B1'] = '用戶(hù)名'self.sheet['C1'] = '用戶(hù)頭像'self.sheet['D1'] = '用戶(hù)博客網(wǎng)址'self.sheet['E1'] = '粉絲數(shù)'self.sheet['F1'] = '點(diǎn)贊數(shù)'self.sheet['G1'] = '上周排名'self.sheet['H1'] = '博客等級(jí)'self.sheet['I1'] = '排名時(shí)間'def __params(self, offset):self.offset = offset"""構(gòu)造請(qǐng)求參數(shù)"""self.params = {"username": "weixin_39190897","page": str(self.offset),"size": "10"}def spider(self):"""構(gòu)造 多頁(yè) 爬取"""for i in range(1, 11):self.__params(i)url = self.url + urlencode(self.params)r = requests.get(url, headers=self.header)if r.status_code == 200:r.encoding = r.apparent_encodingyield r.json()else:print('[info] request error ! the status_code is ' + r.status_code)time.sleep(0.5)def parse_json(self, r_json):"""根據(jù)網(wǎng)站請(qǐng)求返回的json包 進(jìn)行進(jìn)一步分析"""# 第一層first_data = r_json.get('data')if first_data:# 第二層list_data = first_data.get('list')if list_data: # 判空f(shuō)or i in list_data:rank = i.get("ranking")head_image = i.get('avatar')user_nickname = i.get('user_nickname') # 用戶(hù)名username = i.get('username') # 用戶(hù)idfans_num = i.get('fans_num') # 粉絲fav_num = i.get('fav_num') # 獲贊last_rank = i.get('last_ranking') # 上周排名leave = i.get('profile_level').get('level') # 博客等級(jí)if rank and head_image and user_nickname and user_nickname and username and fans_num \and fav_num and last_rank and leave:# 這里保存數(shù)據(jù) 只是為了方便轉(zhuǎn)換其他保存格式 僅僅是保存excel中用到列表yield {'rank': rank,'user_nickname': user_nickname,'head_image': head_image,'username': 'https://blog.csdn.net/' + username,'fans_num': fans_num,'fav_num': fav_num,'last_rank': last_rank,'leave': leave}def down(self, item):"""保存至excel表格"""now_time = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime())leave_list = []for value in item.values():leave_list.append(value)leave_list.append(now_time)self.sheet.append(leave_list)def main(self):"""調(diào)用函數(shù)"""print('The spider is start!')for content in self.spider():for item in self.parse_json(content):self.down(item)self.workbook.save(filename='CSDNTop100.xlsx')self.workbook.close()print('The CSDNTop100 spider is over!')a = CSDNSpider() a.main()此處代碼中出現(xiàn)使用了 yield 的函數(shù),屬于Python生成器(generator),跟普通函數(shù)不同的是,生成器是一個(gè)返回迭代器的函數(shù),只能用于迭代操作,更簡(jiǎn)單點(diǎn)理解生成器就是一個(gè)迭代器。
在調(diào)用生成器運(yùn)行的過(guò)程中,每次遇到 yield 時(shí)函數(shù)會(huì)暫停并保存當(dāng)前所有的運(yùn)行信息,返回 yield 的值, 并在下一次執(zhí)行 next() 方法時(shí)從當(dāng)前位置繼續(xù)運(yùn)行。調(diào)用一個(gè)生成器函數(shù),返回的是一個(gè)迭代器對(duì)象。
更多 yield 關(guān)鍵詞的理解可參考:python中yield的用法詳解——最簡(jiǎn)單,最清晰的解釋。
運(yùn)行效果
在Pycharm中運(yùn)行腳本:
腳本運(yùn)行成功后在項(xiàng)目工程目錄下自動(dòng)生成?CSDNTop100.xlsx?文件:
最后就是見(jiàn)證奇跡的時(shí)刻,打開(kāi)瞅瞅:
反爬技術(shù)
1、通過(guò)user-agent來(lái)控制訪(fǎng)問(wèn)
user-agent 能夠使服務(wù)器識(shí)別出用戶(hù)的操作系統(tǒng)及版本、cpu類(lèi)型、瀏覽器類(lèi)型和版本。很多網(wǎng)站會(huì)設(shè)置 user-agent 白名單,只有在白名單范圍內(nèi)的請(qǐng)求才能正常訪(fǎng)問(wèn)。所以在我們的爬蟲(chóng)代碼中需要設(shè)置 user-agent 偽裝成一個(gè)瀏覽器請(qǐng)求。有時(shí)候服務(wù)器還可能會(huì)校驗(yàn) Referer,所以還可能需要設(shè)置 Referer (用來(lái)表示此時(shí)的請(qǐng)求是從哪個(gè)頁(yè)面鏈接過(guò)來(lái)的)。
# 設(shè)置請(qǐng)求頭信息 headers = {'Host': 'https://blog.csdn.net','Referer': 'https://blog.csdn.net/weixin_43499626/article/details/85875090','User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36'} response = requests.get("http://www.baidu.com", headers=headers)2、通過(guò)IP來(lái)限制
當(dāng)我們用同一個(gè)ip多次頻繁訪(fǎng)問(wèn)服務(wù)器時(shí),服務(wù)器會(huì)檢測(cè)到該請(qǐng)求可能是爬蟲(chóng)操作。因此就不能正常的響應(yīng)頁(yè)面的信息了。解決辦法常用的是使用IP代理池。網(wǎng)上就有很多提供代理的網(wǎng)站。
proxies = {"http": "http://119.101.125.56","https": "http://119.101.125.1", } response = requests.get("http://www.baidu.com", proxies=random.choices(proxies))3、通過(guò)前端參數(shù)加密
某些網(wǎng)站可能會(huì)將參數(shù)進(jìn)行某些加密,或者對(duì)參數(shù)進(jìn)行拼接發(fā)送給服務(wù)器,以此來(lái)達(dá)到反爬蟲(chóng)的目的。這個(gè)時(shí)候我們可以試圖通過(guò)js代碼,查看破解的辦法。這里就要請(qǐng)出一個(gè)大殺器:”P(pán)hantomJS“。PhantomJS是一個(gè)Python包,他可以在沒(méi)有圖形界面的情況下,完全模擬一個(gè)”瀏覽器“,js腳本驗(yàn)證什么的再也不是問(wèn)題了。
4、通過(guò)robots.txt來(lái)限制爬蟲(chóng)
robots.txt是一個(gè)限制爬蟲(chóng)的規(guī)范,該文件是用來(lái)聲明哪些東西不能被爬取。如果根目錄存在該文件,爬蟲(chóng)就會(huì)按照文件的內(nèi)容來(lái)爬取指定的范圍。但是這實(shí)際上只是一個(gè)”君子協(xié)議“,遵守與否,都在于爬蟲(chóng)的編寫(xiě)者。
總結(jié)
以上是生活随笔為你收集整理的Python采集CSDN博客排行榜数据的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: TortoiseSVN常见用法
- 下一篇: python定义函数,随机生成6位的密码