剛學Python,Python這種工具嘛,當然是用來做爬蟲啦。但是爬蟲有爬取策略,網站製作者也有反爬取策略,所以爲了能夠愉快的抓取數據,就不得不讓自己的爬蟲更加像人
- 爬蟲的所謂的僞裝,第一個,僞裝header頭的User-Agent,沒什麼意思,比較簡單,事先弄好幾個header頭放在代碼裏,然後在合適的時候,比如說已經抓取了一頁的數據,這個時候,就可以換換header頭了:
#coding:utf-8
'''
@Created on 2017-11-25 16:54:12
@author: 許瑞銳
'''
list= [
"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.1 (KHTML, like Gecko) Chrome/22.0.1207.1 Safari/537.1",
"Mozilla/5.0 (X11; CrOS i686 2268.111.0) AppleWebKit/536.11 (KHTML, like Gecko) Chrome/20.0.1132.57 Safari/536.11",
"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/536.6 (KHTML, like Gecko) Chrome/20.0.1092.0 Safari/536.6",
"Mozilla/5.0 (Windows NT 6.2) AppleWebKit/536.6 (KHTML, like Gecko) Chrome/20.0.1090.0 Safari/536.6",
"Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.1 (KHTML, like Gecko) Chrome/19.77.34.5 Safari/537.1",
"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/536.5 (KHTML, like Gecko) Chrome/19.0.1084.9 Safari/536.5",
"Mozilla/5.0 (Windows NT 6.0) AppleWebKit/536.5 (KHTML, like Gecko) Chrome/19.0.1084.36 Safari/536.5",
"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1063.0 Safari/536.3",
"Mozilla/5.0 (Windows NT 5.1) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1063.0 Safari/536.3",
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_0) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1063.0 Safari/536.3",
"Mozilla/5.0 (Windows NT 6.2) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1062.0 Safari/536.3",
"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1062.0 Safari/536.3",
"Mozilla/5.0 (Windows NT 6.2) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1061.1 Safari/536.3",
"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1061.1 Safari/536.3",
"Mozilla/5.0 (Windows NT 6.1) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1061.1 Safari/536.3",
"Mozilla/5.0 (Windows NT 6.2) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1061.0 Safari/536.3",
"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/535.24 (KHTML, like Gecko) Chrome/19.0.1055.1 Safari/535.24",
"Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/535.24 (KHTML, like Gecko) Chrome/19.0.1055.1 Safari/535.24"
]
這裏可以封裝成函數然後直接調用,隨機更換一個header頭,如果使用默認的header頭簡直就是在告訴人家:“我就是個爬蟲啊,快點ban掉我啊”,像西祠網如果不加header頭訪問的話就會彈出503錯誤
- 然而header頭能起到的作用非常小,就只能騙下非常非常菜的程序員或者是一些根本不做反爬策略的網站,所以這個時候我們就需要加代理。代理是啥子呢?顧名思義,代理訪問。當爬蟲想要高速的抓取數據的時候很容易遭到網站後臺的禁止,因爲普通人根本手速沒那麼快,但是代碼可以啊。當你發現有個ip在以一秒鐘一百個頁面的瀏覽速度查看你的網站的時候,你肯定明白這是個爬蟲。而代理的作用就是“換臉”,將訪問的來源ip直接代理了,這時爬蟲的ip都改變了,網站後臺自然識別不出來。
# -*- coding: utf-8 -*-
'''
@Created on 2017-11-25 16:31:36
@author: 許瑞銳
'''
import random,requests,time,re
from spider import user_agent,database
def get_random_header():
headers={'User-Agent':random.choice(user_agent.list),'Accept':"text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8",'Accept-Encoding':'gzip'}
return headers
def scraw_proxies(page_num,scraw_url="http://www.xicidaili.com/nt/"):
scraw_ip=list()
available_ip=list()
for page in range(1,page_num):
print("抓取第%d頁代理IP" %page)
url=scraw_url+str(page)
r=requests.get(url,headers=get_random_header())
r.encoding='utf-8'
pattern = re.compile('<td class="country">.*?alt="Cn" />.*?</td>.*?<td>(.*?)</td>.*?<td>(.*?)</td>', re.S)
scraw_ip= re.findall(pattern, r.text)
for ip in scraw_ip:
if(test_ip(ip)==True):
print('%s:%s通過測試,添加進可用代理列表' %(ip[0],ip[1]))
available_ip.append(ip)
else:
pass
print("代理爬蟲暫停10s")
time.sleep(10)
print("爬蟲重啓")
print('抓取結束')
return available_ip
if __name__=="__main__":
available_ip=scraw_proxies(3)
我這上的是西刺網這個免費代理網站,scraw_proxies()這個函數就是用來爬取裏面的免費代理的,爬取過程也很容易,就是老一套的正則表達式或者用beautifulsoup也行,不過我查看西刺網的網頁源碼的時候發現它前端代碼寫的不是很規範,於是放棄bs了上網找了個正則表達式抄下來。但是有個問題,我如何驗證爬取的代理是可用可靠的呢?沒錯,test_ip()函數就是幹這個活的。
def test_ip(ip,test_url='http://2017.ip138.com/ic.asp',time_out):
proxies={'http': ip[0]+':'+ip[1]}
try_ip=ip[0]
#print(try_ip)
try:
r=requests.get(test_url,headers=get_random_header(),proxies=proxies,timeout=time_out)
if r.status_code==200:
r.encoding='gbk'
result=re.search('\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}',r.text)
result=result.group()
if result[:9]==try_ip[:9]:
print(r.text)
print('測試通過')
return True
else:
print('%s:%s 攜帶代理失敗,使用了本地IP' %(ip[0],ip[1]))
return False
else:
print('%s:%s 請求碼不是200' %(ip[0],ip[1]))
return False
except:
print('%s:%s 請求過程錯誤' %(ip[0],ip[1]))
return False
這個函數就是驗證代理的有效性的啦。思路是這樣的,爬蟲讓代理訪問能夠查詢IP的網站,如果返回的status_code爲200且用正則表達式抓取下的IP地址確實爲代理的IP地址,那麼這個代理纔是確實有效。嗯,網上很多教程讓訪問百度的網站,如果返回的status_code==200那麼就認爲代理有效,其實這樣不對,我親身體驗了下,發現抓取下來的代理拿去訪問百度都能用,我心想不對啊,免費代理成功率不可能這麼高啊。於是改了下代碼,代理拿去訪問你的IP,發現成功的全TM是我自己的ip,我自己的IP訪問百度當然沒TM的問題了,這是個很詭異的問題,如果你的代理不成功那麼就會默認使用你自己的IP訪問網站。於是我改變策略,用代理訪問查詢IP的網站你的IP,再抓取查詢IP網站上顯示的IP,如果前幾位能對上那就說明加代理訪問成功啦(事實上大部分代理都不可用)。