爬蟲技術(shù)(1) 前置知識(shí)與架構(gòu)

1. requests 庫的使用

安裝

pip install requests

發(fā)送請(qǐng)求

(1)請(qǐng)求方式

  • Get 查看資源
  • POST 增加資源
  • PUT 修改資源
  • PATCH 少量修改資源
  • DELETE 刪除資源
  • HEAD 查看響應(yīng)頭
  • OPTIONS 查看可用的請(qǐng)求方法

(2)請(qǐng)求api

  • get 方式 后面跟拼接參數(shù): requests.get(url, params={'key1':'value1'})
  • 表單參數(shù)提交: requests.post(url, data={'key1':'value1','key2':'value2'})
  • json 參數(shù)提交 requests.post(url, json={'key1':'value1','key2':'value2'})
  • 提交文件 requests.post(url, files={'file':open('sss.csv','rb')})

(3)請(qǐng)求異常處理(異常放在requests.exceptions包內(nèi))

  1. 請(qǐng)求超時(shí)處理:except exceptions.Timeout
    requests.get(url, timeout=10)
  2. 錯(cuò)誤碼異常處理 except exceptions.HTTPError
    如果響應(yīng)的狀態(tài)碼不為200,response.raise_for_status() 會(huì)拋出狀態(tài)碼異常:response.raise_for_status()
import requests
from requests.exceptions import Timeout, ConnectionError, RequestException,.HTTPError
 
try:
    resp = requests.get('http://httpbin.org/get', timeout=0.5)
    print(resp.status_code)
except Timeout: # 訪問超時(shí)的錯(cuò)誤
    print('Timeout')
except ConnectionError: # 網(wǎng)絡(luò)中斷連接錯(cuò)誤
    print('Connect error')
except RequestException: # 父類錯(cuò)誤
    print('Error')
except HTTPError: # 錯(cuò)誤碼
    print('響應(yīng)狀態(tài)非200')

Demo

//偽造頭信息
headers = {"Host":" music.163.com",

"User-Agent":" Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:56.0) Gecko/20100101 Firefox/56.0",

}
requests.get(url,headers = headers)

#  文件上傳
files = {'file' : open('logo.gif','rb')}
resp = requests.post('http://httpbin.org/post', files=files)

解析響應(yīng)

1.響應(yīng)狀態(tài)碼:

1XX:消息

2XX 請(qǐng)求成功:
200 返回響應(yīng)成功 201 資源建立成功 204 成功響應(yīng)周拐,無返回  

3XX 重定向:
301 永久移動(dòng) 302 暫時(shí)移動(dòng) 304 上次的get請(qǐng)求訪問過的內(nèi)容

4XX 客戶端錯(cuò)誤:
400 請(qǐng)求有問題 401 認(rèn)證問題 403 權(quán)限不足宾抓,服務(wù)器拒絕執(zhí)行 404 頁面不存在

5XX 服務(wù)器端錯(cuò)誤:
500 服務(wù)器端有bug 501 無法識(shí)別請(qǐng)求的方法502 網(wǎng)關(guān)錯(cuò)誤 503 服務(wù)不可用

2. 響應(yīng)的api

基本api

  • status_code 狀態(tài)碼

  • reason 響應(yīng)情況

  • headers 獲取響應(yīng)頭

  • url( 響應(yīng)的地址

  • request 獲得響應(yīng)對(duì)應(yīng)的請(qǐng)求的對(duì)象揉稚,有headers 和 body

內(nèi)容相關(guān)的api:

  • content() 讀取二進(jìn)制內(nèi)容 常用于圖片下載
  • text() 解析為解碼后的字符串(可以修改requests.encoding = 'utf-8' 默認(rèn)是utf-8)
  • json() 將json格式的響應(yīng)解析為python中的字典

demo

一.圖片下載
from contextlib import closing
url = 'http://pic.58pic.com/58pic/16/42/96/56e58PICAu9_1024.jpg'
 #偽造頭信息
 headers = {'User-Agent':'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:51.0) 
Gecko/20100101 Firefox/51.0'}
#關(guān)閉流的方式發(fā)送請(qǐng)求
 with closing(requests.get(url,headers=headers)) as response:
 with open('demo.jpg','wb') as f:
#每128個(gè)字節(jié)寫入一次文件
        for chunk in response.iter_content(128):
            f.write(chunk)

二和蚪、事件鉤子(Event Hooks) 發(fā)送請(qǐng)求恤左,在獲取響應(yīng)時(shí)回調(diào)鉤子函數(shù)

import requests
def func(response,*args,**kws):
    pass
requests.get(url,hooks=dict(response=func))

使用進(jìn)階

(1) HTTP認(rèn)證

  1. 基本認(rèn)證,驗(yàn)證賬號(hào)與密碼
    requests.get(url,auth=(name,password))

  2. OAUTH認(rèn)證

from requests.auth import AuthBase

class GitHubAuth(AuthBase):
def __init__(self, token):
  self.token= token
def __call__(self,r):
#request 加headers
  r.headers['Authorization'] = '  '.join(['token', self.token])
def oauth_advanced():
  #傳入access token
auth = GithubAuth('dddsfsdfsdfasf')
response = requests.get(url,auth = auth)
  1. 代理設(shè)置

有些網(wǎng)站會(huì)限制 IP 訪問頻率鸣皂,超過頻率就斷開連接摔踱。這個(gè)時(shí)候我們就需要使用到代理虐先,我們可以通過為任意請(qǐng)求方式提供proxies參數(shù)來配置單個(gè)請(qǐng)求。

import requests
 
proxies = {
    "http": "http://10.10.1.10:3128",
    "https": "http://10.10.1.10:1080",
}
resp = requests.get('http://www.baidu.com', proxies=proxies)
print(resp.status_code)

也可以通過環(huán)境變量 HTTP_PROXYHTTPS_PROXY 來配置代理派敷。
有些代理需要加上用戶名和密碼的蛹批,代理可以使用http://user:password@host/語法,比如:

proxies = {
    "http": "http://user:pass@10.10.1.10:3128/",
}

2. xpath的使用

安裝

pip install lxml

Demo

from lxml import etree

# 字符串讀取html
html_str = '''  
<div>
    <ul>
         <li class="item-0"><a href="link1.html">first item</a></li>
         <li class="item-1"><a href="link2.html">second item</a></li>
         <li class="item-inactive"><a href="link3.html"><span class="bold">third item</span></a></li>
         <li class="item-1"><a href="link4.html">fourth item</a></li>
         <li class="item-0"><a href="link5.html">fifth item</a></li>
     </ul>
 </div>
'''

html = etree.HTML(html_str)
#也可以從文件讀取html html = etree.parse('hello.html') 

res = html.xpath("http://div/ul/li[@class='item-0']/a")

for e in res:
    print(e.text)
    print(e.get("href"))

xpath語法

1. 獲取 <li> 標(biāo)簽的所有 class
result = html.xpath('//li/@class')
print result
運(yùn)行結(jié)果:
['item-0', 'item-1', 'item-inactive', 'item-1', 'item-0']

2. 獲取 <li> 標(biāo)簽下 href 為 link1.html 的 <a> 標(biāo)簽
result = html.xpath('//li/a[@href="link1.html"]')
print result
運(yùn)行結(jié)果
[<Element a at 0x10ffaae18>]

3. 獲取 <li> 標(biāo)簽下的所有 <span> 標(biāo)簽
不能這樣寫:result = html.xpath('//li/span')
因?yàn)?/ 是用來獲取子元素的篮愉,而 <span> 并不是 <li> 的子元素腐芍,所以,要用雙斜杠

result = html.xpath('//li//span')
print result
運(yùn)行結(jié)果
[<Element span at 0x10d698e18>]

4. 獲取 <li> 標(biāo)簽下的所有 class试躏,不包括 <li>
result = html.xpath('//li/a//@class')
print result
運(yùn)行結(jié)果
['blod']

5. 獲取最后一個(gè) <li> 的 <a> 的 href
result = html.xpath('//li[last()]/a/@href')
print result
運(yùn)行結(jié)果
['link5.html']

6. 獲取倒數(shù)第二個(gè)元素的內(nèi)容
result = html.xpath('//li[last()-1]/a')
print result[0].text
運(yùn)行結(jié)果
fourth item

7. 獲取 class 為 bold 的標(biāo)簽名
result = html.xpath('//*[@class="bold"]')
print result[0].tag
運(yùn)行結(jié)果
span

進(jìn)階用法

# 對(duì)節(jié)點(diǎn)進(jìn)行xpath查詢 處理字段缺失
tables = html.xpath("http://div[@class='indent']//table")
for table in tables:
            score = table.xpath(".//span[@class='rating_nums']")[0].text
            description = "暫無簡(jiǎn)介"
            node = table.xpath(".//span[@class='inq']")
            if node:
                description = node[0].text

# 獲取某節(jié)點(diǎn)內(nèi)所有文字內(nèi)容
# <li class="item-1">sss <a href="link2.html">second item</a> ss</li>
res = html.xpath('//li')[1]

text = res.xpath('string(.)')
print(l1)

# 結(jié)果: sss second item ss

進(jìn)階

MongoDB的使用 設(shè)置下載緩存和實(shí)現(xiàn)多進(jìn)程任務(wù)

教程

爬蟲教程

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末猪勇,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子颠蕴,更是在濱河造成了極大的恐慌泣刹,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,544評(píng)論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件裁替,死亡現(xiàn)場(chǎng)離奇詭異项玛,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)弱判,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,430評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門襟沮,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人昌腰,你說我怎么就攤上這事开伏。” “怎么了遭商?”我有些...
    開封第一講書人閱讀 162,764評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵固灵,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我劫流,道長(zhǎng)巫玻,這世上最難降的妖魔是什么丛忆? 我笑而不...
    開封第一講書人閱讀 58,193評(píng)論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮仍秤,結(jié)果婚禮上熄诡,老公的妹妹穿的比我還像新娘。我一直安慰自己诗力,他們只是感情好凰浮,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,216評(píng)論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著苇本,像睡著了一般袜茧。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上瓣窄,一...
    開封第一講書人閱讀 51,182評(píng)論 1 299
  • 那天笛厦,我揣著相機(jī)與錄音,去河邊找鬼俺夕。 笑死递递,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的啥么。 我是一名探鬼主播,決...
    沈念sama閱讀 40,063評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼贰逾,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼悬荣!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起疙剑,我...
    開封第一講書人閱讀 38,917評(píng)論 0 274
  • 序言:老撾萬榮一對(duì)情侶失蹤氯迂,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后言缤,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體嚼蚀,經(jīng)...
    沈念sama閱讀 45,329評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,543評(píng)論 2 332
  • 正文 我和宋清朗相戀三年管挟,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了轿曙。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,722評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡僻孝,死狀恐怖导帝,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情穿铆,我是刑警寧澤您单,帶...
    沈念sama閱讀 35,425評(píng)論 5 343
  • 正文 年R本政府宣布,位于F島的核電站荞雏,受9級(jí)特大地震影響虐秦,放射性物質(zhì)發(fā)生泄漏平酿。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,019評(píng)論 3 326
  • 文/蒙蒙 一悦陋、第九天 我趴在偏房一處隱蔽的房頂上張望蜈彼。 院中可真熱鬧,春花似錦叨恨、人聲如沸柳刮。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,671評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽秉颗。三九已至,卻和暖如春送矩,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背栋荸。 一陣腳步聲響...
    開封第一講書人閱讀 32,825評(píng)論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留晌块,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,729評(píng)論 2 368
  • 正文 我出身青樓匆背,卻偏偏與公主長(zhǎng)得像呼伸,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子钝尸,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,614評(píng)論 2 353

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