導語
前段時間在學習Python爬取豆瓣電影信息的過程中發(fā)現(xiàn)如果同一IP短時間內(nèi)持續(xù)訪問的話會導致IP地址被限制訪問,頁面提示要求登錄。解決IP地址被封除了在爬取數(shù)據(jù)時增加延遲,另外一個方法就是使用代理。代理IP從何而來呢?一是網(wǎng)上購買,長期穩(wěn)定使用;二是爬取代理網(wǎng)上的免費代理,絕大多數(shù)無法使用。
本文以爬取西刺代理-國內(nèi)HTTP代理為例,爬取網(wǎng)頁數(shù)據(jù)、驗證代理IP有效性并將有效的IP寫入CSV文件:

導入模塊
import requests,random,csv,re,time
from multiprocessing import Pool,cpu_count
常見的User_Agent
這部分在網(wǎng)上搜索會找到很多,如常見瀏覽器User-Agent大全,我們可以將一些常見的添加到列表里并隨機獲取一個以模擬不同瀏覽器請求網(wǎng)頁數(shù)據(jù)。
userAgentList =[
'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36 OPR/26.0.1656.60
Opera/8.0 (Windows NT 5.1; U; en)',
'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:34.0) Gecko/20100101 Firefox/34.0',
'Mozilla/5.0 (X11; U; Linux x86_64; zh-CN; rv:1.9.2.10) Gecko/20100922 Ubuntu/10.10 (maverick) Firefox/3.6.10',
'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/534.57.2 (KHTML, like Gecko) Version/5.1.7 Safari/534.57.2',
'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.11 (KHTML, like Gecko) Chrome/23.0.1271.64 Safari/537.11',
'Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko'
]
爬取代理及多進程驗證IP是否可用
def getProxyList(url):
proxyIPs =[] #代理IP數(shù)組
headers = {'User-Agent': random.choice(userAgentList)}
try:
res= requests.get(url,headers=headers,timeout = 3)
if res.status_code ==200:
# 獲取元組數(shù)組,元組是(ip,port)格式
results = re.findall(r'<td>(\d+\.+\d+\.+\d+\.+\d+)</td>.*?>(.*?)</td>',res.text,re.S) # 使用正則表達式
for (ip,port) in results:
proxyIP = 'http://{}:{}'.format(ip,port)
# 將所有代理IP 添加到數(shù)組里
proxyIPs.append(proxyIP)
# 創(chuàng)建進程池對代理IP驗證
pool = Pool(cpu_count())
pool.map(verifyProxy,proxyIPs)
pool.join()
pool.close()
else:
print('無法獲取網(wǎng)頁內(nèi)容')
except Exception as e:
print('出錯啦:{}'.format(e))
我們爬取到的代理并不是都能正常使用的,我之前爬取了20頁的數(shù)據(jù),通過測試發(fā)現(xiàn)只有28個代理能用。
def verifyProxy(ip):
# 驗證代理是否可用的網(wǎng)站(可以使用其他大型網(wǎng)站)
verifyUrl = 'https://www.baidu.com'
proxy = {'http' : ip,
'https': ip
}
headers = {'User-Agent': random.choice(userAgentList)}
with open('代理IP地址文件.csv', 'a+', newline='') as f:
writer = csv.writer(f)
try:
# 使用代理IP訪問百度,如果能夠正常訪問,則將IP寫入CSV
r = requests.get(verifyUrl,proxies = proxy,headers = headers,timeout = 5) #這邊的超時時間自行定義
if r.status_code == 200:
writer.writerow([ip])
f.close()
except Exception as e:
print('出錯啦{}'.format(e))
爬取多頁并打印耗時時間
def main():
start = time.strftime('%Y-%m-%d %H:%M:%S',time.localtime((time.time())))
print('開始時間是:{}'.format(start))
for page in range(1,20):
url = 'http://www.xicidaili.com/wt/{}'.format(page)
getProxyList(url)
end = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime((time.time())))
print('結(jié)束時間是:{}'.format(end))
if __name__ == '__main__':
main()
結(jié)語
雖然我在程序中采用了
多進程進行IP驗證,但是爬取20頁的數(shù)據(jù)、IP進行驗證及寫入CSV文件這整個過程耗時12分鐘左右。
本文只使用了多進程對IP地址進行驗證,如何使用多進程同時處理爬取代理和驗證代理,以進一步提高效率呢?