爬蟲1.1-基礎知識+requests庫
目錄
- 爬蟲-基礎知識+requests庫
- 1. 狀態返回碼
- 2. URL各個字段解釋
- 2. requests庫
- 3. requests庫爬蟲的基本流程
爬蟲-基礎知識+requests庫
關於html的知識,可以到w3school中進行了解學習。http://www.w3school.com.cn/html/index.asp,水平有限,這裏不多提及。
1. 狀態返回碼
標誌這這一次的請求狀態,成功或失敗,失敗原因大概是什麽
200:請求正常,服務器正常返回數據。 不代表爬去到正確信息了
301:永久重定向,比如訪問www.jingdong.com 會重定向到www.jd.com
302:臨時重定向,比如訪問一個需要登陸的網站時,因為沒有登陸會重定向到登陸頁面
400:請求的url在服務器上找不到。url錯誤
403:服務器拒絕,權限不夠
500:服務器內部錯誤,服務器出現bug
2. URL各個字段解釋
URL:scheme://host:port/path/?query-string=xxx#anchor
scheme: 代表的是訪問的協議,http https ftp...
host:主機名,域名,baidu.com
port:端口號,一般瀏覽器默認80
path:查詢路徑,文件在服務器中的位置
query-string:查詢字符串,例如www.baidu.com/s?wd=python
anchor:錨點,前端用於給關鍵詞定位的
示例
https://www.baidu.com/s?ie=UTF-8&wd=python
https://baike.baidu.com/item/html標簽/6999473?fr=aladdin#2
2. requests庫
requests庫是python中一個非常強大的網絡請求庫,常用來寫一些小爬蟲、
瀏覽器抓包:使用谷歌瀏覽器,按F12點擊Network,再按F5刷新頁面即可抓包查看請求頭(Requst Headers)和
表單(Form Data)數據,拷貝到自己的代碼中即可防止被服務器發現一個爬蟲。
get請求:
import requests response = requests.get(url, headers=headers) print(response.content.decode(‘utf-8‘)) # 網頁編碼不全都是utf-8格式,也有可能是gbk,可以在瀏覽器中右鍵查看網頁源代碼,一般在最開頭幾行有標識 utf-8或則gb2313 # headers配置件下方代碼塊。
headers 是需要構建的請求頭字典,配置見下方代碼塊。
網頁源代碼:response.content.decode(‘utf-8‘) 最好自己解碼, temp.text自動解碼,但可能出錯
其他屬性response.encoding響應頭編碼 response.status_code查看響應碼 response.url 查看url
post請求:
import requests
data = {
‘username‘: ‘xxx‘,
‘password‘: ‘xx‘,
‘random‘: ‘xxxx‘,
}
headers = {
‘Cookie‘: "xxx",
‘Referer‘: ‘xx‘,
‘User-Agent‘: ‘xxxx‘
}
response = requests.post(url, data=data, headers=headers)
其中url應該是可以接受post請求的url
data是提交的表單,需要在瀏覽器中先檢查好格式,然後在代碼中模仿
headers是請求頭,為字典形式,一般需要加入‘User-Agent‘ ‘Cookie‘ ‘Referer‘字段,這幾個字段的知識百度即可,註意headers通常都是需要添加的,如果沒有添加,很可能被識別為爬蟲,從而被服務器拒絕訪問。
代理:
proxy = {‘http‘:‘ip:port‘}
temp = requests.get(url, headers=headers, params=params, proxies=proxy)
從參數來看似乎可以加入多個代理ip,內部有自動處理方法
會話:
s = requests.Session() 創建會話類
s.post/get (url1,xxx) 成功後會保存cookie等信息 然後再訪問其他網頁即可
s.get(url2)
處理HTTPS協議時,證書不被信任,直接request.get(url, verify=False)
更多實戰代碼,請查看其他筆記。
3. requests庫爬蟲的基本流程
前面提到requests庫適用於小爬蟲,對於整站爬取這種工作是不適宜的,原因在於url防重控制和異步問題。
3.1 爬蟲框架
第一步,分析需要爬取頁面的規則,例如爬取拉勾網搜索python關鍵詞之後的全部崗位,拉勾網先給出一個職位簡介列表,點擊沒一個簡介即可進入每個職位的詳情頁,而我們的爬蟲正是需要解析這些詳情頁裏面的內容。根據瀏覽器的user-agent, cookie, referer等字段偽造請求頭。
第二步,分析url變化規則,例如boss直聘網的python職位列表變化在於page=x,所以只要在代碼中加入
for x in (1, max+1)
,就可以遍歷所有的列表,在其中取得詳情頁的url,其中max為網站中給出的最大值。
https://www.zhipin.com/c101270100/?query=python&page=4
第三步,使用xpath或者正則,在列表頁中提取出詳情頁的url並訪問,利用xpath或者正則表達式提取想要的信息
第四步,將信息存儲(json, csv, txt等)
3.2 一個樣例代碼
# 古詩文網爬蟲,正則表達式提取信息
import re
import csv
import requests
# 頭部
HEADERS = {
‘User-Agent‘: ‘Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36‘,
‘Cookie‘: ‘sec_tc=AQAAAOnYGRKNjAwAc6jZqzitZLqPPmaN; Hm_lvt_04660099568f561a75456483228a9516=1543214277; ASP.NET_SessionId=q2b21uwthctq4aad0vbc5x5e; Hm_lpvt_04660099568f561a75456483228a9516=1543214320‘,
‘referer‘: ‘https://www.gushiwen.org/default_1.aspx‘,
}
# 處理頁面信息的函數
def parse_page(url):
global data # data是列表,用於存儲每篇古詩字典
response = requests.get(url, headers=HEADERS)
response_text = response.text
# 四個正則表達式 選中大範圍再縮小範圍, .*?作用是非貪婪模式 獲取兩個標簽之間的所有內容
titles = re.findall(r‘<div\sclass="cont">.*?<b>(.*?)</b>‘, response_text,re.DOTALL)
dynasties = re.findall(r‘<p class="source">.*?<a.*?>(.*?)</a>‘, response_text)
authors = re.findall(r‘<span>:</span>.*?<a.*?>(.*?)</a>‘, response_text)
contens = re.findall(r‘<div class="contson" id=.*?>(.*?)</div>‘, response_text, re.DOTALL)
poeminfo = {}
for i in contens:
contens[contens.index(i)] = re.sub(r‘<.*?>‘, "", i).strip() # .strip()函數用於去除\n 空格等
# zip函數是將多個列表依次打包,[1,2] [3,4]會被組合成(1,3) (2,4)
for value in zip(titles, dynasties, authors, contens,):
title, dynasty, author, content = value # 這裏相當於解包並對應取值
poeminfo = {
‘title‘: title,
‘dynasty‘: dynasty,
‘author‘: author,
‘content‘: content
}
data.append(poeminfo) # 存入列表
def get_url():
url_list = []
base_url = ‘https://www.gushiwen.org/default_{}.aspx‘
for i in range(1, 100):
url = base_url.format(i)
url_list.append(url)
return url_list
def csv_write(data):
# 構造頭部
csv_headers = [‘title‘, ‘dynasty‘, ‘author‘, ‘content‘]
with open(‘gushici.csv‘, ‘w‘, encoding=‘utf-8‘, newline=‘‘) as fp:
writer = csv.DictWriter(fp, csv_headers)
writer.writeheader()
writer.writerows(data)
fp.close()
if __name__ == ‘__main__‘:
data = []
list = get_url()
for url in list:
parse_page(url)
for i in data:
print(i)
print("=" * 50)
print(url)
print("=" * 50)
csv_write(data) # 將獲取的數據寫入csv文件
爬蟲1.1-基礎知識+requests庫