爬蟲是一個應用程序html
是指某一個用於爬取數據的應用程序,爬取的目標能夠是整個互聯網 也能夠是單獨的某一個服務器python
在CS結構中 爬蟲屬於client 客戶端mysql
爬蟲的價值:互聯網中最重要的就是數據,爬蟲首要任務就是要經過網絡去獲取服務器的數據:來爲本身創造價值git
首先明確 爬蟲是客戶端 要爬的數據在服務器上存儲,因此須要藉助網絡編程,底層的網絡協議已經有現成的封裝不須要本身寫,數據傳輸已經解決,問題是對方給個人數據我能不能看懂,個人數據對方可否看懂github
絕大多數網絡傳輸都是採用的HTTPweb
HTTP 協議 超文本傳輸協議ajax
1.明確要爬取得url地址正則表達式
分析請求web頁面(chrome)原生軟件(抓包工具如Charles)redis
2.發送請求sql
第三方requests模塊 高度封裝了HTTP
內置的urllib模塊
selenium是由於一些網站須要人機交互(點擊拖拽等等操做)
針對移動app可使用代理服務器,能夠截獲app端發送的請求信息,Chaeles(青花瓷)
3.接收響應
瀏覽器接受響應後會渲染頁面進行展現 沒法拿到數據
因此更多狀況下使用瀏覽器來分析請求詳情
requests和urllib都會直接返回響應體
selenium提供了find_element***的接口用於獲取數據
4.解析數據
re
BeautifulSoup 封裝了經常使用的正則表達式
移動端返回的/ajax返回的json數據 直接json.load
5.存儲數據
mysql等關係型數據庫
Mongodb redis 等菲關係型數據庫 通常用在高併發爬蟲中
接口測試工具 postman paw(mac能夠自動生成請求代碼)
Scrapy爬蟲框架
爬取梨視頻
爬取的流程
1.爬取首頁中全部的視頻的id
2.拼接詳情地址並請求
3.經過re解析數據
4.將結果存儲爲json數據
分析請求頭中有用的信息
1.user-agent用來識別客戶端類型
2.refer 用來識別 用戶從哪一個頁面過來的
3.Cookie 當頁面須要驗證用戶身份時 使用
響應頭:
location 當請求被重定向時 就會帶有該字段 能夠經過狀態碼30* 來識別重定向
發送post請求
requests 中
get請求 參數放在地址後或是使用params參數來制定一個字典
post請求:參數使用data參數來指定 是一個字典
若是是登陸請求通常都須要帶token
先發送請求獲取token的值 token值必定都在一個form表單中
HTTP請求分析:
首先要明確的是:爬蟲的核心原理就是模擬瀏覽器發送HTTP協議來獲取服務器上的數據,那麼要想服務器接收你的請求,則必須將本身的請求假裝的足夠像,這就須要咱們去分析瀏覽器是如何發送的HTTP請求
其次:HTTP協議是基於請求響應模型的,客戶端發送請求到服務器,服務器接受請求,處理後返回數據,須要關注的重點在於請求數據,只有服務器任何合格合法的請求才會獲得服務器的響應
利用chrome開發者工具來分析請求
chrome瀏覽器提供強大的開發者工具咱們能夠利用它來查看瀏覽器與服務器的整個通信過程
請求流程分析
請求地址:瀏覽器發送的請求URL地址
請求方法:
get:中文須要URL編碼,參數跟在地址後面
post:參數放在body中
請求頭:cookie須要登錄成功才能訪問的頁面就須要傳遞cookie,不然不要要
user-agent,:用戶代理,驗證客戶端的類型
referer,引用頁面,判斷是從那個頁面點擊過來的
請求體:只在post請求時須要關注,一般post請求參數都放在請求體中,例如登陸的用戶名和密碼
響應頭:
location:重定向後的目標地址,盡在狀態碼爲3**時出現,須要考慮重定向時的方法,參數等.瀏覽器會自動重定向,requests模塊也會
set-cookie:服務器返回的cookie信息,在訪問一些隱私頁面時須要帶上cookie
響應體
服務器返回的數據,可能有如下幾種類型
HTML格式的靜態頁面 須要解析獲取的數據
json格式的結構化數據 直接就是純粹的疏忽
二進制數據(圖片視頻等) 經過文件操做直接寫入文件
requests模塊的使用:
get請求:請求參數
1.參數拼接時中文須要URLEncode,可使用urllib中的編碼函數來完成
from urllib.parse import urlencode
import requests
params={"word":"美女"}必須以字典類型傳入須要編碼的數據,獲得拼接後的參數字符串
res = urlencode(params,encoding="utf-8")
url = "https://www.baidu.com/s"
url = url+"?"+res #拼接參數
response = erquests.get(url)
with open("test.html","wb") as f:
f.write(response.content)
2.也能夠直接將請求參數傳給get的函數的param參數,get將會自動完成編碼
import requests
params={"wd":"美女"}
url = "https://www.baidu.com/s"直接傳params參數
response =requests.get(url,params=params)
上述代碼沒法完成請求完成的數據,由於百度服務器有限制必須指定用戶代理,user-agent爲瀏覽器才行
import requests
params={"wd":"美女"}
url="https://www.baidu.com/s"
headers = {"user-agent":"Mozilla/5.0...."}
response=request.get(url,params=params,heades=headers)
能夠在headers中直接添加鍵值對也能夠單獨使用個體方法的cookies參數
url = "https://github.com/yangyuanhu"
headers = {
"User-Agent" : 'Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36
(KHTML, like Gecko) Chrome/71.0.3578.98 Mobile Safari/537.36',
"Cookie":"_octo=GH1.1.1155792533.1532919557; _ga=GA1.2.1847433334.1534242542;
has_recent_activity=1; user_session=Z5AQmC_Wv4wvM-_Nc3Bj0PQn6nITSonDcPkw4GZ1g0jFIqbe;
__Host-user_session_same_site=Z5AQmC_Wv4wvM-_Nc3Bj0PQn6nITSonDcPkw4GZ1g0jFIqbe;
logged_in=yes; dotcom_user=yangyuanhu; tz=Asia%2FShanghai; _gat=1;
_gh_sess=eERwWHk1NVBjOEhIRmxzckcrcWlpVCtUM2hWL0prNlIyNXdTdC9ab0FSZWR5MEZlYW5OVGNo
TEdJQUN0K0xkNXVmTEVpK2RRU1VZTUF6NkJHM1JMejNtaVhReXg2M3Vsb0JvcG8vNDNENjNBcXVvcFE4T
mp4SFhpQ3Z3S2ZZZEIwTGNkVW5BR01qVHlCNEFqTnZFcllhN3NwT1VJblZYWElLOGowN3ZaZVpZTFVHQlF
tZkh3K1hnclBWalB1Mk1XLS1wNjFjMlBxUHljU2paK2RXU3M5eDB3PT0%3D--8cdf657174d2acac7cc0459da667accc8a2d0f5e",
"Referer": "https://github.com/"
}
response = requests.get(url,headers=headers)
with open("test.html","wb") as f:
f.write(response.content)
使用cookies參數 注意須要拆分爲單獨的鍵值對
requests模塊自動處理(session)cookies
post請求不一樣之處僅在於參數提交經過post方法的data參數來指定:模擬登錄流程並爬取github私有頁面
模擬登陸流程並爬取github私有頁面
```python
import requests
import re
user_agent = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_5) AppleWebKit/537.36 (KHTML, like Gecko)
Chrome/71.0.3578.98 Safari/537.36"
# 建立一個會話
session = requests.session()
# 1.請求登陸頁面
res = session.get("https://github.com/login",headers={
"Referer": "https://github.com/",
"User-Agent": user_agent
})
print(res.status_code)
token = re.search('name="authenticity_token" value="(.*?)"',res.text).group(1)
print(token)
# 2.發送登陸請求,帶上cookie,帶上請求體,帶上token
res2 = session.post("https://github.com/session",
headers = {
"Referer": "https://github.com/login",
"User-Agent": user_agent},
data={
"commit": "Sign in",
"utf8": "✓",
"authenticity_token": token,
"login": "oldboyedujerry",
"password": "123654asdAsd"},
allow_redirects = True)
print(res2.status_code)
# 訪問我的主頁
res3 = session.get("https://github.com/settings/profile",
headers={
"User-Agent": user_agent,
"Referer": "https://github.com/login"
})
print(res3.status_code)
with open("tt.html","wt") as f:
f.write(res3.text)
# 判斷是否登陸成功
print("oldboyedujerry" in res3.text)
```
注意一般登陸時都會帶token,須要現貨區token才能進行post登陸
## session的使用
使用會話來完成請求,會話會自動幫咱們保存和提交cookie
```python
user_agent = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_5) AppleWebKit/537.36 (KHTML, like
Gecko) Chrome/71.0.3578.98 Safari/537.36"
# 建立一個會話
session = requests.session()
# 1.請求登陸頁面
res = session.get("https://github.com/login",headers={
"Referer": "https://github.com/",
"User-Agent": user_agent
})
print(res.status_code)
token = re.search('name="authenticity_token" value="(.*?)"',res.text).group(1)
print(token)
# 2.發送登陸請求,帶上cookie,帶上請求體
res2 = session.post("https://github.com/session",
headers = {
"Referer": "https://github.com/login",
"User-Agent": user_agent},
data={
"commit": "Sign in",
"utf8": "✓",
"authenticity_token": token,
"login": "oldboyedujerry",
"password": "123654asdAsd"},
allow_redirects = False
)
print(res2.status_code)
# 訪問我的主頁
res3 = session.get("https://github.com/settings/profile",
headers={
"User-Agent": user_agent,
"Referer": "https://github.com/login"
})
print(res3.status_code)
with open("tt.html","wt") as f:
f.write(res3.text)
# 判斷是否登陸成功
print("oldboyedujerry" in res3.text)
requests模塊爲咱們封裝了獲取cookie的方法:token須要手動獲取
login_url= "http://github.com/login"
resp = requests.get(login_url)
cookie = resp.cookies.get_dict()
token = re.search("authenticity_token" value="(.*?) />",resp.text)
# 2.請求登陸接口
login_url = "https://github.com/session"
resp2 = requests.post(login_url,
headers={
"Referer": "https://github.com/login",
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.77 Safari/537.36",
},
data={"commit": "Sign in",
"utf8": "✓",
"authenticity_token": token,
"login": "oldboyedujerry",
"password": "123654asdAsd",
"webauthn-support": "supported"},
cookies = cookie)
經過使用session方法(能夠出去獲取cookie的過程簡便操做)