⑴ python 在爬蟲中timeout設置超時有什麼作用
是為了防止url不可訪問,或者響應速度太慢而造成的時間浪費。
比如,你要爬取1000個網站,如果有100個需要30s才能返回數據,你等待他們返回的話就需要3000s了,如果你設置10s超時,那麼就能知道最長需要多久1000個可以爬完。
如果解決了您的問題請採納!
如果未解決請繼續追問
⑵ Python爬蟲基礎代碼提問
爬到的文本結尾有換行符,用strip方法拿掉就行了
⑶ python爬取大量數據(百萬級)
當用python爬取大量網頁獲取想要的數據時,最重要的問題是爬蟲中斷問題,python這種腳本語言,一中斷
進程就會退出,怎麼在中斷後繼續上次爬取的任務就至關重要了。這里就重點剖析這個中斷問題。
第一個問題: 簡單點的用動態代理池就能解決,在爬取大量數據的時候,為了速度不受影響,建議使用一些緩
存的中間件將有效的代理 ip 緩存起來,並定時更新。這里推薦 github 這個倉庫
https://github.com/jhao104/proxy_pool , 它會做ip有效性驗證並將 ip 放入 redis ,不過實現過於復雜
了,還用到了 db ,個人覺得最好自己修改一下。困難點的就是它會使用別的請求來進行判斷當前的ip是否
是爬蟲,當我們過於聚焦我們的爬蟲請求而忽略了其他的請求時,可能就會被伺服器判定為爬蟲,進而這個ip
會被列入黑名單,而且你換了ip一樣也會卡死在這里。這種方式呢,簡單點就用 selenium + chrome 一個一個
去爬,不過速度太慢了。還是自己去分析吧,也不會過復雜的。
第二個問題: 網路連接超時是大概率會遇到的問題,有可能是在爬取的時候本地網路波動,也有可能是爬
取的服務端對ip做了限制,在爬取到了一定量級的時候做一些延遲的操作,使得一些通用的 http 庫超時
( urllib )。不過如果是服務端動的手腳一般延遲不會太高,我們只需要人為的設置一個高一點的
timeout 即可(30 秒),最好在爬取開始的時候就對我們要用的爬取庫進行一層封裝,通用起來才好改
動。
第三個問題: 在解析大量靜態頁面的時候,有些靜態頁面的解析規則不一樣,所以我們就必須得做好斷點
續爬的准備了( PS : 如果簡單的忽略錯誤可能會導致大量數據的丟失,這就不明智了)。那麼在調試的過
程中斷點續爬有個解決方案,就是生產者和消費者分離,生產者就是產生待爬 url 的爬蟲,消費者就是爬取
最終數據的爬蟲。最終解析數據就是消費者爬蟲了。他們通過消息中間件連接,生產者往消息中間件發送待
爬取的目標信息,消費者從裡面取就行了,還間接的實現了個分布式爬取功能。由於現在的消費中間件都有
ack 機制,一個消費者爬取鏈接失敗會導致消息消費失敗,進而分配給其他消費者消費。所以消息丟失的
概率極低。不過這里還有個 tips , 消費者的消費超時時間不能太長,會導致消息釋放不及時。還有要開啟
消息中間價的數據持久化功能,不然消息產生過多而消費不及時會撐爆機器內存。那樣就得不償失了。
第四個問題: 這種情況只能 try except catch 住了,不好解決,如果單獨分析的話會耗費點時間。但在
大部分數據 (99%) 都正常的情況下就這條不正常拋棄就行了。主要有了第三個問題的解決方案再出現這
種偶爾中斷的問就方便多了。
希望能幫到各位。
⑷ 怎樣用Python設計一個爬蟲模擬登陸知乎
給你一個例子,可以看看:
import requests
import time
import json
import os
import re
import sys
import subprocess
from bs4 import BeautifulSoup as BS
class ZhiHuClient(object):
"""連接知乎的工具類,維護一個Session
2015.11.11
用法:
client = ZhiHuClient()
# 第一次使用時需要調用此方法登錄一次,生成cookie文件
# 以後可以跳過這一步
client.login("username", "password")
# 用這個session進行其他網路操作,詳見requests庫
session = client.getSession()
"""
# 網址參數是賬號類型
TYPE_PHONE_NUM = "phone_num"
TYPE_EMAIL = "email"
loginURL = r"http://www.hu.com/login/{0}"
homeURL = r"http://www.hu.com"
captchaURL = r"http://www.hu.com/captcha.gif"
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2490.86 Safari/537.36",
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8",
"Accept-Encoding": "gzip, deflate",
"Host": "www.hu.com",
"Upgrade-Insecure-Requests": "1",
}
captchaFile = os.path.join(sys.path[0], "captcha.gif")
cookieFile = os.path.join(sys.path[0], "cookie")
def __init__(self):
os.chdir(sys.path[0]) # 設置腳本所在目錄為當前工作目錄
self.__session = requests.Session()
self.__session.headers = self.headers # 用self調用類變數是防止將來類改名
# 若已經有 cookie 則直接登錄
self.__cookie = self.__loadCookie()
if self.__cookie:
print("檢測到cookie文件,直接使用cookie登錄")
self.__session.cookies.update(self.__cookie)
soup = BS(self.open(r"http://www.hu.com/").text, "html.parser")
print("已登陸賬號: %s" % soup.find("span", class_="name").getText())
else:
print("沒有找到cookie文件,請調用login方法登錄一次!")
# 登錄
def login(self, username, password):
"""
驗證碼錯誤返回:
{'errcode': 1991829, 'r': 1, 'data': {'captcha': '請提交正確的驗證碼 :('}, 'msg': '請提交正確的驗證碼 :('}
登錄成功返回:
{'r': 0, 'msg': '登陸成功'}
"""
self.__username = username
self.__password = password
self.__loginURL = self.loginURL.format(self.__getUsernameType())
# 隨便開個網頁,獲取登陸所需的_xsrf
html = self.open(self.homeURL).text
soup = BS(html, "html.parser")
_xsrf = soup.find("input", {"name": "_xsrf"})["value"]
# 下載驗證碼圖片
while True:
captcha = self.open(self.captchaURL).content
with open(self.captchaFile, "wb") as output:
output.write(captcha)
# 人眼識別
print("=" * 50)
print("已打開驗證碼圖片,請識別!")
subprocess.call(self.captchaFile, shell=True)
captcha = input("請輸入驗證碼:")
os.remove(self.captchaFile)
# 發送POST請求
data = {
"_xsrf": _xsrf,
"password": self.__password,
"remember_me": "true",
self.__getUsernameType(): self.__username,
"captcha": captcha
}
res = self.__session.post(self.__loginURL, data=data)
print("=" * 50)
# print(res.text) # 輸出腳本信息,調試用
if res.json()["r"] == 0:
print("登錄成功")
self.__saveCookie()
break
else:
print("登錄失敗")
print("錯誤信息 --->", res.json()["msg"])
def __getUsernameType(self):
"""判斷用戶名類型
經測試,網頁的判斷規則是純數字為phone_num,其他為email
"""
if self.__username.isdigit():
return self.TYPE_PHONE_NUM
return self.TYPE_EMAIL
def __saveCookie(self):
"""cookies 序列化到文件
即把dict對象轉化成字元串保存
"""
with open(self.cookieFile, "w") as output:
cookies = self.__session.cookies.get_dict()
json.mp(cookies, output)
print("=" * 50)
print("已在同目錄下生成cookie文件:", self.cookieFile)
def __loadCookie(self):
"""讀取cookie文件,返回反序列化後的dict對象,沒有則返回None"""
if os.path.exists(self.cookieFile):
print("=" * 50)
with open(self.cookieFile, "r") as f:
cookie = json.load(f)
return cookie
return None
def open(self, url, delay=0, timeout=10):
"""打開網頁,返回Response對象"""
if delay:
time.sleep(delay)
return self.__session.get(url, timeout=timeout)
def getSession(self):
return self.__session
if __name__ == '__main__':
client = ZhiHuClient()
# 第一次使用時需要調用此方法登錄一次,生成cookie文件
# 以後可以跳過這一步
# client.login("username", "password")
# 用這個session進行其他網路操作,詳見requests庫
session = client.getSession()
⑸ Python爬蟲筆記(二)requests模塊get,post,代理
import requests
base_url = 'https://www..com'
response = requests.get(base_url)
url=請求url,
headers =請求頭字典,
params = 請求參數字典。
timeout = 超時時長,
)---->response對象
伺服器響應包含:狀態行(協議,狀態碼)、響應頭,空行,響應正文
字元串格式:response.text
bytes類型:response.content
response.headers['cookie']
response.text獲取到的字元串類型的響應正文,
其實是通過下面的步驟獲取的:
response.text = response.content.decode(response.encoding)
產生的原因:編碼和解碼的編碼格式不一致造成的。
str.encode('編碼')---將字元串按指定編碼解碼成bytes類型
bytes.decode('編碼')---將bytes類型按指定編碼編碼成字元串。
a、response.content.decode('頁面正確的編碼格式')
<meta http-equiv="content-type" content="text/html;charset=utf-8">
b、找到正確的編碼,設置到response.encoding中
response.encoding = 正確的編碼
response.text--->正確的頁面內容。
a、沒有請求參數的情況下,只需要確定url和headers字典。
b、get請求是有請求參數。
在chrome瀏覽器中,下面找query_string_params,
將裡面的參數封裝到params字典中。
c、分頁主要是查看每頁中,請求參數頁碼欄位的變化,
找到變化規律,用for循環就可以做到分頁。
requests.post(
url=請求url,
headers = 請求頭字典,
data=請求數據字典
timeout=超時時長
)---response對象
post請求一般返回數據都是json數據。
(1)response.json()--->json字元串所對應的python的list或者dict
(2)用 json 模塊。
json.loads(json_str)---->json_data(python的list或者dict)
json.mps(json_data)--->json_str
post請求能否成功,關鍵看**請求參數**。
如何查找是哪個請求參數在影響數據獲取?
--->通過對比,找到變化的參數。
變化參數如何找到參數的生成方式,就是解決這個ajax請求數據獲取的途徑。
**尋找的辦法**有以下幾種:
(1)寫死在頁面。
(2)寫在js中。
(3)請求參數是在之前的一條ajax請求的數據裡面提前獲取好的。
代理形象的說,他是網路信息中轉站。
實際上就是在本機和伺服器之間架了一座橋。
a、突破自身ip訪問現實,可以訪問一些平時訪問不到網站。
b、訪問一些單位或者團體的資源。
c、提高訪問速度。代理的伺服器主要作用就是中轉,
所以一般代理服務裡面都是用內存來進行數據存儲的。
d、隱藏ip。
FTP代理伺服器---21,2121
HTTP代理伺服器---80,8080
SSL/TLS代理:主要用訪問加密網站。埠:443
telnet代理 :主要用telnet遠程式控制制,埠一般為23
高度匿名代理:數據包會原封不動轉化,在服務段看來,就好像一個普通用戶在訪問,做到完全隱藏ip。
普通匿名代理:數據包會做一些改動,伺服器有可能找到原ip。
透明代理:不但改動數據,還會告訴服務,是誰訪問的。
間諜代理:指組織或者個人用於記錄用戶傳輸數據,然後進行研究,監控等目的的代理。
proxies = {
'代理伺服器的類型':'代理ip'
}
response = requests.get(proxies = proxies)
代理伺服器的類型:http,https,ftp
代理ip:http://ip:port
⑹ 關於Python爬蟲 403的錯誤
那是網站檢測到你的是爬蟲,拒絕了連接。可以減少訪問頻率,偽裝多種headers試試
⑺ 如何入門 Python 爬蟲
#-*-coding:utf-8-*-
importre
importurllib2
fromcollectionsimportdeque
queue=deque()
visited=set()
url='入口頁面,可以換成別的
req_header={'User-Agent':'Mozilla/5.0(WindowsNT6.3;WOW64;Trident/7.0;rv:11.0)likeGecko'}
req_timeout=20
queue.append(url)
cnt=0
whilequeue:
url=queue.popleft()#隊首元素出隊
visited|={url}#標記為已訪問
print(u'已經抓取:'+str(cnt)+u'正在抓取<---'+url)
cnt+=1
req=urllib2.Request(url,None,req_header)
urlop=urllib2.urlopen(req,None,req_timeout)
try:
data=urlop.read().decode('utf-8')
except:
continue
#正則表達式提取頁面中所有隊列,並判斷是否已經訪問過,然後加入待爬隊列
linkre=re.compile('href="(.+?)"')
forxinlinkre.findall(data):
print(x)
if'http'inxandxnotinvisited:
queue.append(x)
print(u'加入隊列--->'+x)
⑻ python多線程爬蟲,每個線程都循環requests,線程數目過多會不會導致requests請求timeout
有可能 因為客戶端的資源(cpu,內存,網路等)是有限的
⑼ Python爬蟲,有沒有什麼方法能讓一次請求時間超長後跳過
在body裡面設置一個timeout。然後再包一層try except補獲異常。跳過異常繼續執行代碼,這樣應該可以達到目的
⑽ 全方面的掌握Requests庫的使用【python爬蟲入門進階】(02)
上一篇文章簡單的介紹了 爬蟲相關的基礎知識點,介紹了一個標准爬蟲程序的三個步驟 。這篇文章就讓我們接著來學習。
本文重點介紹requests庫的使用以及爬蟲協議。之前也寫了一篇 Requests庫使用的博客 ,有興趣的小夥伴可以去看看。
前面介紹了Requests庫是用來抓取網頁源碼,請求介面的利器,整體上是要比urllib庫的request更加好用的庫。官網上將其稱之為唯一一個非轉基因的Python HTTP庫,人類可以安全享用。
Requests庫有7個主要方法。
不過我們平常最常用的方法還是GET方法和POST方法。
get請求方法是爬蟲中最常用到的方法,因為爬蟲主要就是爬取網頁的信息。最基礎的使用是
這里需要通過 res.encoding='utf-8' 設置響應結果的編碼格式是utf-8。不然可能會出現中文亂碼
如果響應結果是二進制數據的話則需要通過 res.content 方法來提取響應結果。
設置編碼的方式也可以是 res.content.decode('utf-8') 。
即
有時候get請求也需要傳入參數,這里可以直接將參數拼接到URL上或者通過params參數傳入一個字典。
運行結果是:
get請求只能傳入簡單的參數,如果參數比較復雜或者傳入的參數比較多的話則GET請求就不再適用了,這時候就需要適用post請求方法了。
Post請求的請求類型有三種:
以表單的方式提交數據是POST請求的默認的請求格式,只需要將參數放在一個字典中進行傳入即可。
這里將請求頭的數據放在一個名為header的字典中,然後在請求時通過headers參數傳入。在請求中設置了內容類型是 application/json ,編碼格式是 charset=utf-8
傳入的是一個json字元串,通過data參數進行傳入。json字元串可以直接寫也可以通過 json.mps(dict) 方法將一個字典序列化,就像下面這樣。
文件上傳與本節爬蟲的內容無關,在此就不過多介紹了。有興趣的小夥伴可以看看 Python中如何編寫介面,以及如何請求外部介面 這篇文章。
在網路請求中,我們常常會遇到狀態碼是3開頭的重定向問題,在Requests中是默認開啟允許重定向的,即遇到重定向時,會自動繼續訪問。通過將allow_redirects 屬性設置為False不允許重定向。
通過timeout屬性可以設置超時時間,單位是秒。get方法和post方法均可設置。
通過status_code屬性可以獲取介面的響應碼。
有時候我們使用了抓包工具,這時候由於抓包證書提供的證書並不是受信任的數字證書頒發機構頒發的,所以證書的驗證會失敗,所以我們就需要關閉證書驗證。在請求的時候把verify參數設置為False就可以關閉證書驗證了。
爬蟲協議也叫做robots協議,告訴網路蜘蛛哪些頁面可以爬取,哪些頁面不能爬取
爬蟲文件的規范是:
允許所有的機器人
本文詳細介紹了Request庫的使用