零基础爬虫requests初阶教程,手把手教你爬数据
目錄
一、環(huán)境與工具
二、學(xué)爬蟲必備知識(shí)
三、簡(jiǎn)單體驗(yàn) requests
四、get 請(qǐng)求
3.1 基礎(chǔ)講解一
3.3 基礎(chǔ)講解二
3.2 基礎(chǔ)講解三
3.5 獲取請(qǐng)求頭
3.6 添加請(qǐng)求頭
3.5 知乎爬取+反扒技術(shù)
3.6 抓取二進(jìn)制數(shù)據(jù)
3.7 美女私房照爬取( 準(zhǔn)備發(fā)車)
四、 POST 請(qǐng)求
4.1 數(shù)據(jù)表單提交
4.2 添加請(qǐng)求頭
4.3 提交json
4.4 普通文件上傳
一、環(huán)境與工具
環(huán)境:jupyter
如果你沒有安裝該工具和不會(huì)使用,請(qǐng)看這一篇文章:pycharm安裝配置與使用詳細(xì)教程
你可能還會(huì)需要這兩篇文章:
1-親測(cè)jupyter打不開瀏覽器
2-設(shè)置默認(rèn)打開文件夾
模塊安裝:
演示安裝:
?安裝完畢:
二、學(xué)爬蟲必備知識(shí)
如果你python基礎(chǔ)都不會(huì),建議你先大佬寫的python基礎(chǔ)專欄:python全棧基礎(chǔ)教程
他的基礎(chǔ)專欄包括最基本的基礎(chǔ),re正則表達(dá)式,畫圖,文件處理,django,mysql操作處理等,如果你基礎(chǔ)都不會(huì),建議你先收藏本篇內(nèi)容,去學(xué)完基礎(chǔ),再來看本篇文章。
三、簡(jiǎn)單體驗(yàn) requests
以百度為例子:
網(wǎng)址:https://www.baidu.com/
import requests r = requests.get('https://www.baidu.com/') print(type(r)) print(r.status_code) print(type(r.text)) print(r.text) print(r.cookies)運(yùn)行結(jié)果:
輸出結(jié)果得到了一個(gè) Response 對(duì)象,然后分別輸出了 Response 的類型、狀態(tài)碼、響應(yīng)體的類型、內(nèi)容以及 Cookies。或許在這里你還看不懂,那么請(qǐng)看下去,你會(huì)懂的!
四、get 請(qǐng)求
3.1 基礎(chǔ)講解一
還是以百度為例子:
網(wǎng)址:https://www.baidu.com/
為什么我這里只演示了百度?因?yàn)檫@個(gè)不會(huì)被反扒,如果被反扒,則會(huì)返回為空。大家可以試試別的網(wǎng)址,比如我的博客地址,基本返回為空。但不必?fù)?dān)心,后續(xù)會(huì)學(xué)習(xí)并分享給大家有關(guān)反扒的。
我們用get請(qǐng)求網(wǎng)址,打印txt則獲取到百度頁面源碼:
import requests r = requests.get('https://www.baidu.com/') print(r.text)輸出結(jié)果:
3.3 基礎(chǔ)講解二
我們以CSDN為例:
這里就直接使用requests模塊的get函數(shù)直接來獲取(get和urlopen是相同的),主要是這個(gè)更方便些:
import requestsr=requests.get('https://mp.csdn.net/mp_blog/manage/article')print(r.status_code)#打印狀態(tài)碼 print(r.text)#打印文本 print(r.cookies)#打印cookie運(yùn)行結(jié)果:
?再舉例子:
import requestsr=requests.post('https://www.csdn.net/?spm=1011.2124.3001.5359') s=requests.put('https://www.csdn.net/?spm=1011.2124.3001.5359')print(r.status_code) print(r.text) print(s.status_code) print(s.text)運(yùn)行結(jié)果:
?雖然請(qǐng)求失敗但不影響,主要是介紹下用requests模塊的話,可以很簡(jiǎn)單的方式請(qǐng)求,比如說put,post,delete這些之間換一下就換了一個(gè)請(qǐng)求方法。這里之所以請(qǐng)求失敗是因?yàn)槲覀?strong>被反扒了。?
3.2 基礎(chǔ)講解三
首先,構(gòu)建一個(gè)最簡(jiǎn)單的 GET 請(qǐng)求,請(qǐng)求的鏈接為 http://httpbin.org/get,該網(wǎng)站會(huì)判斷如果客戶端發(fā)起的是 GET 請(qǐng)求的話,它返回相應(yīng)的請(qǐng)求信息.
代碼:
運(yùn)行結(jié)果:
?此時(shí)我們可以發(fā)現(xiàn),我們成功發(fā)起了 GET 請(qǐng)求,返回結(jié)果中包含請(qǐng)求頭、URL、IP 等信息。
那么,對(duì)于 GET 請(qǐng)求,如果要附加額外的信息,一般怎樣添加呢?比如現(xiàn)在想添加兩個(gè)參數(shù),其中 name 是 germey,age 是 22。
要構(gòu)造這個(gè)請(qǐng)求鏈接,是不是要直接寫成:
r = requests.get('http://httpbin.org/get?name=germey&age=22')這同樣很簡(jiǎn)單,利用 params 這個(gè)參數(shù)就好了,示例如下:
import requests data = { 'name': 'germey', 'age': 22 } r = requests.get("http://httpbin.org/get", params=data) print(r.text)運(yùn)行結(jié)果:
?通過返回信息我們可以判斷,請(qǐng)求的鏈接自動(dòng)被構(gòu)造成了:http://httpbin.org/get?age=22&name=germey
另外,網(wǎng)頁的返回類型實(shí)際上是 str 類型,但是它很特殊,是 JSON 格式的。所以,如果想直接解析返回結(jié)果,得到一個(gè)字典格式的話,可以直接調(diào)用 json 方法。
示例如下:
import requests r = requests.get("http://httpbin.org/get") print(type(r.text)) print(r.json()) print(type(r.json()))運(yùn)行結(jié)果:
?我們可以發(fā)現(xiàn),調(diào)用 json 方法,就可以將返回結(jié)果是 JSON 格式的字符串轉(zhuǎn)化為字典。
3.4 獲取cookie
import requestsheaders={'User-Agent':'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.71 Safari/537.36' }#請(qǐng)求頭url='https://www.csdn.net/?spm=1011.2124.3001.5359'r=requests.get(url=url,headers=headers)print(r.cookies)#直接打印運(yùn)行結(jié)果:
3.5 獲取請(qǐng)求頭
手動(dòng)獲取:
點(diǎn)擊右鍵,選擇檢查,再選擇network,刷新一下(ctrl+r),隨機(jī)選其中一個(gè)內(nèi)容,(或如圖)如下將 User-Agent 后的內(nèi)容復(fù)制出來就行:
3.6 添加請(qǐng)求頭
我們也可以通過 headers 參數(shù)來傳遞頭信息。比如,在下面我們的面 “知乎” 的例子中,如果不傳遞 headers,就不能正常請(qǐng)求,請(qǐng)求結(jié)果為403:
import requestsr = requests.get("https://www.zhihu.com/explore") print(r.text)運(yùn)行結(jié)果:
但如果加上 headers 并加上 User-Agent 信息,那就沒問題了:
import requestsheaders = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36' } r = requests.get("https://www.zhihu.com/explore", headers=headers) print(r.text)?運(yùn)行結(jié)果:?
?此時(shí)可以看到加請(qǐng)求頭成功了。
為什么加請(qǐng)求頭??加上后可以模擬正常瀏覽器,防止被反扒。
3.5 知乎爬取+反扒技術(shù)
先獲取cookies:
import requests headers={'User-Agent':'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.11 (KHTML, like Gecko) Chrome/23.0.1271.64 Safari/537.11' } #請(qǐng)求頭 url='http://www.zhihu.com' r=requests.get(url=url,headers=headers) print(r.cookies)運(yùn)行結(jié)果:
?或者登錄知乎,找到cookie:
?用這里的cookie來獲取網(wǎng)頁:
import requests headers={'Cookie':'_zap=05c6669b-d609-4b2d-836d-c4e713ed7831; d_c0="AFAfZacmRBOPTjQC-e4owqO1ysBeTeL3Vzw=|1623771050"; _xsrf=bqDX2DchG0ZA7EC9pkRRGEaVn3QkTrZi; captcha_session_v2="2|1:0|10:1636804292|18:captcha_session_v2|88:WjRRYXljbms2MmtweWJzMU9SQ1NrRlpPa2Q0ZytFWlJ0THpud2ZJQ1YxUktQbEg3a0EyTWNnYUprdUNhUW9qbQ==|0c9ffe3bd4b71219514487843501772ea80b4d14e4009a776f9a7529f4a56613"; Hm_lvt_98beee57fd2ef70ccdd5ca52b9740c49=1636541465,1636541647,1636771333,1636804292; l_n_c=1; r_cap_id="YmNjZjMyOGVlZTM3NDRlNjlkYTkxZTY1Yjg1ODdhMjA=|1636804293|d3a977b05d2ed03f94aa4cc909fbb3232619c402"; cap_id="M2NkNWEzZDRkYmMwNDYwZThkMmRhNDU0M2QzZWU5ZGE=|1636804293|b9ec3e1451d5cd873d86525d785868acfa08c556"; l_cap_id="MjA5MGU4YjUyOGZhNGZlYWI3NzY0NGQ1ZWY5MjcyYmM=|1636804293|9ec9d7a50eb48b4e5450a2962e8090f86bf1281c"; n_c=1; SESSIONID=iachyVQaPqsWF2xcGJGC7c7RvcJvrlusR39loCQax90; __snaker__id=dYZWp8JZry4pPHne; JOID=VFsUAknVovxY469NX9IDpZ1o-iVLucGfM578Hj6B1o0PppkwPh8GcD7iqE9cjgkePw8VMqkDcY9vrgPNPl3u4uc=; osd=UV8UB0zQpvxd5qpJX9cGoJlo_yBOvcGaNpv4HjuE04kPo5w1Oh8DdTvmqEpZiw0eOgoQNqkGdIprrgbIO1nu5-I=; gdxidpyhxdE=7GzbIgu7wGey6y7Z4EeYzrtLlNOZOi08rMg9VqGGe%5Cs2tG9dg0lGBcPR%2BWxzp0u0eY3fRqE%5C1USNlC8qYP4lkOhjflbMytQvptR4ERWDs%5Ck5WyN40f%2FkwXx0cWg60pasJBZBPHI%2FGH66x5r3m2Ogsly%2BNpDDUt6T0qN%2F1vaur8USEdZT%3A1636805203141; _9755xjdesxxd_=32; z_c0=Mi4xdzNpOEV3QUFBQUFBVUI5bHB5WkVFeGNBQUFCaEFsVk56X1I4WWdBb2VFN0ZJUzQ3RVJDRGNVT2FmdDYxT0xXNXV3|1636804303|204653c41cd7c89747145d10e635c8403ba38549; tst=r; Hm_lpvt_98beee57fd2ef70ccdd5ca52b9740c49=1636804313; NOT_UNREGISTER_WAITING=1; KLBRSID=b5ffb4aa1a842930a6f64d0a8f93e9bf|1636804319|1636804289','User-Agent':'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.11 (KHTML, like Gecko) Chrome/23.0.1271.64 Safari/537.11','host':'www.zhihu.com', } url='http://www.zhihu.com' r=requests.get(url=url,headers=headers) print(r.text)運(yùn)行結(jié)果:
?返回結(jié)果有知乎里的相關(guān)內(nèi)容,這樣就是成功登錄知乎了
再提一點(diǎn)session,它可以實(shí)現(xiàn)同一個(gè)站點(diǎn)進(jìn)去不同頁面:
運(yùn)行結(jié)果:
3.6 抓取二進(jìn)制數(shù)據(jù)
如果想抓取圖片、音頻、視頻等文件,應(yīng)該怎么辦呢?
圖片、音頻、視頻這些文件本質(zhì)上都是由二進(jìn)制碼組成的,由于有特定的保存格式和對(duì)應(yīng)的解析方式,我們才可以看到這些形形色色的多媒體。所以,想要抓取它們,就要拿到它們的二進(jìn)制碼。
3.6.1 示例一
下面以 GitHub 的站點(diǎn)圖標(biāo)為例來看一下:
import requestsr = requests.get("https://github.com/favicon.ico") print(r.text) print(r.content)運(yùn)行結(jié)果:
?可以注意到,前者出現(xiàn)了亂碼,后者結(jié)果前帶有一個(gè) b,這代表是 bytes 類型的數(shù)據(jù)。由于圖片是二進(jìn)制數(shù)據(jù),所以前者在打印時(shí)轉(zhuǎn)化為 str 類型,也就是圖片直接轉(zhuǎn)化為字符串,這理所當(dāng)然會(huì)出現(xiàn)亂碼。
接著,我們將剛才提取到的圖片保存下來:
運(yùn)行后即可保存完成!!!可以自己設(shè)定保存位置哦!!
3.6.2 示例二
以爬取我自己的頭像為例子:
保存代碼如下,運(yùn)行即可保存,位置資源!!!:?
import requests headers={'User-Agent':'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.11 (KHTML, like Gecko) Chrome/23.0.1271.64 Safari/537.11', } url='https://profile.csdnimg.cn/2/B/0/1_qq_25990967.jpg' r = requests.get(url=url,headers=headers) with open('phpto.jpg', 'wb') as f:f.write(r.content)3.7 美女私房照爬取( 準(zhǔn)備發(fā)車)
第一部分:定義要爬取的標(biāo)簽和正在爬取的頁數(shù)
def UserUrl(theme,pagenum):url = "https://tuchong.com/rest/tags/%(theme)s/posts?page=%(pagenum)s&count=20&order=weekly" % {'theme': urllib.parse.quote(theme), 'pagenum': pagenum}#print(url)return url?第二部分:防止反扒
def GetHtmltext(url):head = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36"}try:r = requests.get(url, headers=head, timeout=30)r.raise_for_status() #如果返回的狀態(tài)碼不是200,就到except中return rexcept:pass第三部分:定義獲取一個(gè)pagenum頁面中的所有圖集的URL鏈接的函數(shù)
def PictureFatherUrl(user_url):try:raw_data = GetHtmltext(user_url)j_raw_data = json.loads(raw_data.text) #將獲取的網(wǎng)頁轉(zhuǎn)化為Python數(shù)據(jù)結(jié)構(gòu)# print(j_raw_data)father_url = [] #將每個(gè)圖集的url定義為father_url的一個(gè)列表for i in j_raw_data['postList']: #解析出的j_raw_data是一個(gè)多重字典,在這里先將postList字典的內(nèi)容取出來father_url.append(i['url']) #然后再取出鍵為“url”的值return father_urlexcept:return第四部分:定義獲取一個(gè)圖集中所有圖片的url鏈接
def PictureUrl(url):try:html = GetHtmltext(url)#利用正則表達(dá)式來匹配url_list = list(re.findall('<img id="image\d+" class="multi-photo-image" src="([a-zA-z]+://[^\s]*)" alt="">', html.text))return url_listexcept:pass第五部分:
#定義一個(gè)圖集中所有圖片的下載 def Download(url):url_list = PictureUrl(url)for i in url_list:r = GetHtmltext(i)file_name = os.path.join(save_path, i.split('/')[-1])with open(file_name, 'wb') as f:f.write(r.content)f.close()time.sleep(random.uniform(0.3, 0.5)) #為防止被反爬,在這里random了0.3-0.5的數(shù),然后在下載一張圖片后,sleep一下print('下載成功保存至 %s' % file_name)主函數(shù)部分:
if __name__ == '__main__':theme = input("你選擇的標(biāo)簽(如果你不知道有什么標(biāo)簽,去https://tuchong.com/explore/去看看有什么標(biāo)簽吧,輸入不存在的標(biāo)簽無法下載哦):")pagenum_all = int(input("你要爬取的頁數(shù)(不要太貪心哦,數(shù)字太大會(huì)被封IP的):"))save_path = os.path.join(theme)m = 0if not os.path.exists(save_path):os.makedirs(save_path)print("我知道你沒有創(chuàng)建保存路徑,我把文件存在和此腳本同樣的路徑下的叫做“ %s ”的文件夾下面了" % theme)for i in range(1, pagenum_all+1):n = 0m += 1print("正在下載第%d頁,一共%d頁" % (m, pagenum_all))user_url = UserUrl(theme, i)father_url = PictureFatherUrl(user_url)for j in father_url:n += 1print("正在下載第%d套圖,一共%d套圖" % (n, len(father_url)))Download(j)time.sleep(random.randint(6, 10)) #同樣為了反爬,也random了6-10之間的數(shù),更真實(shí)的模擬人的操作完整源代碼如下:
#coding=gbkimport os import re import json import requests import time import urllib.parse import random#定義要爬取的標(biāo)簽和正在爬取的頁數(shù) def UserUrl(theme,pagenum):url = "https://tuchong.com/rest/tags/%(theme)s/posts?page=%(pagenum)s&count=20&order=weekly" % {'theme': urllib.parse.quote(theme), 'pagenum': pagenum}#print(url)return url#利用requests使用get方法請(qǐng)求url,使用User-Agent是為了防止被反爬,這樣使得我們的爬取行為更像人的行為 def GetHtmltext(url):head = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36"}try:r = requests.get(url, headers=head, timeout=30)r.raise_for_status() #如果返回的狀態(tài)碼不是200,就到except中return rexcept:pass#定義獲取一個(gè)pagenum頁面中的所有圖集的URL鏈接的函數(shù) def PictureFatherUrl(user_url):try:raw_data = GetHtmltext(user_url)j_raw_data = json.loads(raw_data.text) #將獲取的網(wǎng)頁轉(zhuǎn)化為Python數(shù)據(jù)結(jié)構(gòu)# print(j_raw_data)father_url = [] #將每個(gè)圖集的url定義為father_url的一個(gè)列表for i in j_raw_data['postList']: #解析出的j_raw_data是一個(gè)多重字典,在這里先將postList字典的內(nèi)容取出來father_url.append(i['url']) #然后再取出鍵為“url”的值return father_urlexcept:return#定義獲取一個(gè)圖集中所有圖片的url鏈接 def PictureUrl(url):try:html = GetHtmltext(url)#利用正則表達(dá)式來匹配url_list = list(re.findall('<img id="image\d+" class="multi-photo-image" src="([a-zA-z]+://[^\s]*)" alt="">', html.text))return url_listexcept:pass#定義一個(gè)圖集中所有圖片的下載 def Download(url):url_list = PictureUrl(url)for i in url_list:r = GetHtmltext(i)file_name = os.path.join(save_path, i.split('/')[-1])with open(file_name, 'wb') as f:f.write(r.content)f.close()time.sleep(random.uniform(0.3, 0.5)) #為防止被反爬,在這里random了0.3-0.5的數(shù),然后在下載一張圖片后,sleep一下print('下載成功保存至 %s' % file_name)#定義主函數(shù) if __name__ == '__main__':theme = input("你選擇的標(biāo)簽(如果你不知道有什么標(biāo)簽,去https://tuchong.com/explore/去看看有什么標(biāo)簽吧,輸入不存在的標(biāo)簽無法下載哦):")pagenum_all = int(input("你要爬取的頁數(shù)(不要太貪心哦,數(shù)字太大會(huì)被封IP的):"))save_path = os.path.join(theme)m = 0if not os.path.exists(save_path):os.makedirs(save_path)print("我知道你沒有創(chuàng)建保存路徑,我把文件存在和此腳本同樣的路徑下的叫做“ %s ”的文件夾下面了" % theme)for i in range(1, pagenum_all+1):n = 0m += 1print("正在下載第%d頁,一共%d頁" % (m, pagenum_all))user_url = UserUrl(theme, i)father_url = PictureFatherUrl(user_url)for j in father_url:n += 1print("正在下載第%d套圖,一共%d套圖" % (n, len(father_url)))Download(j)time.sleep(random.randint(6, 10)) #同樣為了反爬,也random了6-10之間的數(shù),更真實(shí)的模擬人的操作運(yùn)行:按照提示輸入后回車
?后得到:
?當(dāng)然,難道我的心只有美女小姐姐?NONONO!你只要輸入該網(wǎng)任意一個(gè)標(biāo)簽的都可給下載下來,比如帥哥?你可以測(cè)試一下!!!
四、 POST 請(qǐng)求
前面我們了解了最基本的 GET 請(qǐng)求,另外一種比較常見的請(qǐng)求方式是 POST。
4.1 數(shù)據(jù)表單提交
使用 requests 實(shí)現(xiàn) POST 請(qǐng)求同樣非常簡(jiǎn)單,示例如下:
import requestsdata = {'name': 'germey', 'age': '22'} r = requests.post("http://httpbin.org/post", data=data) print(r.text)這里還是請(qǐng)求 http://httpbin.org/post,該網(wǎng)站可以判斷如果請(qǐng)求是 POST 方式,就把相關(guān)請(qǐng)求信息返回。
運(yùn)行結(jié)果如下:
可以發(fā)現(xiàn),我們成功獲得了返回結(jié)果,其中 form 部分就是提交的數(shù)據(jù),這就證明 POST 請(qǐng)求成功發(fā)送了。
4.2 添加請(qǐng)求頭
代碼如下:
import requests import jsonhost = "http://httpbin.org/" endpoint = "post"url = ''.join([host,endpoint]) headers = {"User-Agent":"test request headers"}r = requests.post(url,headers=headers) print(r.text)運(yùn)行結(jié)果:
可以看到User-Agent部分為我們添加的自定義請(qǐng)求頭。
4.3 提交json
假設(shè)我想提交json格式的內(nèi)容:
# -*- coding:utf-8 -*- import requests import jsonhost = "http://httpbin.org/" endpoint = "post"url = ''.join([host,endpoint]) data = {"sites": [{ "name":"test" , "url":"https://blog.csdn.net/weixin_46211269?spm=1000.2115.3001.5343" },{ "name":"google" , "url":"https://blog.csdn.net/weixin_46211269/article/details/120703631?spm=1001.2014.3001.5501" },{ "name":"weibo" , "url":"https://blog.csdn.net/weixin_46211269/article/details/120659923?spm=1001.2014.3001.5501" }] }r = requests.post(url,json=data) # r = requests.post(url,data=json.dumps(data)) response = r.json() print(response)運(yùn)行結(jié)果:
4.4 普通文件上傳
代碼:
# -*- coding:utf-8 -*- import requests import jsonhost = "http://httpbin.org/" endpoint = "post"url = ''.join([host,endpoint]) #普通上傳 files = {'file':open(r'D:\桌面\a.txt','rb') #打開文件路徑}r = requests.post(url,files=files) print (r.text)運(yùn)行結(jié)果:
總結(jié)
以上是生活随笔為你收集整理的零基础爬虫requests初阶教程,手把手教你爬数据的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: linux 宽字符串,C语言中的多字节字
- 下一篇: tengine简单安装_树莓派使用宝塔面