??前言
博主開始更新爬蟲實(shí)戰(zhàn)教程了,期待你的關(guān)注?。?!
第一篇:Python爬蟲實(shí)戰(zhàn)(一):翻頁(yè)爬取數(shù)據(jù)存入SqlServer
第二篇:Python爬蟲實(shí)戰(zhàn)(二):爬取快代理構(gòu)建代理IP池
點(diǎn)贊收藏博主更有創(chuàng)作動(dòng)力喲,以后常更?。?!
構(gòu)建IP池的目的
使用爬蟲時(shí),大部分網(wǎng)站都有一定的反爬措施,有些網(wǎng)站會(huì)限制每個(gè) IP 的訪問速度或訪問次數(shù),超出了它的限制你的 IP 就會(huì)被封掉。對(duì)于訪問速度的處理比較簡(jiǎn)單,只要間隔一段時(shí)間爬取一次就行了,避免頻繁訪問;而對(duì)于訪問次數(shù),就需要使用代理 IP 來(lái)幫忙了,使用多個(gè)代理 IP 輪換著去訪問目標(biāo)網(wǎng)址可以有效地解決問題。
目前網(wǎng)上有很多的代理服務(wù)網(wǎng)站提供代理服務(wù),也提供一些免費(fèi)的代理,但可用性較差,如果需求較高可以購(gòu)買付費(fèi)代理,可用性較好。當(dāng)然我們也可以自己構(gòu)建代理池,從各種代理服務(wù)網(wǎng)站中免費(fèi)獲取代理 IP,并檢測(cè)其可用性(去訪問百度),再保存到文件中,需要使用的時(shí)候再調(diào)用。
爬取目標(biāo)
我們要爬取的網(wǎng)頁(yè)是:https://www.kuaidaili.com/free/inha/
紅色框就是我們要爬取的內(nèi)容:
博主爬取最后實(shí)現(xiàn)的效果如下:
準(zhǔn)備工作
我用的是python3.8,VScode編輯器,所需的庫(kù)有:requests、etree、time
開頭導(dǎo)入所需用到的導(dǎo)入的庫(kù):
import requests # python基礎(chǔ)爬蟲庫(kù)
from lxml import etree # 可以將網(wǎng)頁(yè)轉(zhuǎn)換為Elements對(duì)象
import time # 防止爬取過快可以睡眠一秒
準(zhǔn)備就緒開始代碼分析!
代碼分析
先講講我的整體思路在逐步分析:
- 第一步:構(gòu)造主頁(yè)url地址,發(fā)送請(qǐng)求獲取響應(yīng)
- 第二步:解析數(shù)據(jù),將數(shù)據(jù)分組
- 第三步:將數(shù)組的數(shù)據(jù)提取出來(lái)
- 第四步:檢測(cè)代理IP的可用性
- 第五步:保存到文件中
第一步
構(gòu)造主頁(yè)的url地址,發(fā)送請(qǐng)求獲取響應(yīng)
# 1.發(fā)送請(qǐng)求,獲取響應(yīng)
def send_request(self,page):
print("=============正在抓取第{}頁(yè)===========".format(page))
# 目標(biāo)網(wǎng)頁(yè),添加headers參數(shù)
base_url = 'https://www.kuaidaili.com/free/inha/{}/'.format(page)
headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.69 Safari/537.36'}
# 發(fā)送請(qǐng)求:模擬瀏覽器發(fā)送請(qǐng)求,獲取響應(yīng)數(shù)據(jù)
response = requests.get(base_url,headers=headers)
data = response.content.decode()
time.sleep(1)
return data
這會(huì)就有小伙伴不明白了,你headers
什么意思啊?
- 防止服務(wù)器把我們認(rèn)出來(lái)是爬蟲,所以模擬瀏覽器頭部信息,向服務(wù)器發(fā)送消息
- 這個(gè) “裝” 肯定必須是要裝的?。?!
第二步
解析數(shù)據(jù),將數(shù)據(jù)分組
從下圖可以看出,我們需要的數(shù)據(jù)都在tr標(biāo)簽中:
所以分組取到tr
標(biāo)簽下:
# 2.解析數(shù)據(jù)
def parse_data(self,data):
# 數(shù)據(jù)轉(zhuǎn)換
html_data = etree.HTML(data)
# 分組數(shù)據(jù)
parse_list = html_data.xpath('//table[@class="table table-bordered table-striped"]/tbody/tr')
return parse_list
第三步
提取分組中我們需要的數(shù)據(jù),IP,類型和端口號(hào)
parse_list = self.parse_data(data)
for tr in parse_list:
proxies_dict = {}
http_type = tr.xpath('./td[4]/text()')
ip_num = tr.xpath('./td[1]/text()')
port_num = tr.xpath('./td[2]/text()')
http_type = ' '.join(http_type)
ip_num = ' '.join(ip_num)
port_num = ' '.join(port_num)
proxies_dict[http_type] = ip_num + ":" + port_num
proxies_list.append(proxies_dict)
這里做了拼接,{'HTTP': '36.111.187.154:8888'}
這種形式存入列表,方便我們使用!
第四步
檢測(cè)IP的可用性,因?yàn)槭敲赓M(fèi)的IP所以有一些可能用不了,有一些訪問速度較慢,這里我們讓拼接好的ip去訪問某度
0.1
秒能訪問成功的保存在另一個(gè)列表中!
def check_ip(self,proxies_list):
headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.69 Safari/537.36'}
can_use = []
for proxies in proxies_list:
try:
response = requests.get('https://www.baidu.com/',headers=headers,proxies=proxies,timeout=0.1)
if response.status_code == 200:
can_use.append(proxies)
except Exception as e:
print(e)
return can_use
第五步
將訪問速度不錯(cuò)的ip保存在文件中,方便我們調(diào)用
def save(self,can_use):
file = open('IP.txt', 'w')
for i in range(len(can_use)):
s = str(can_use[i])+ '\n'
file.write(s)
file.close()
完整代碼
import requests
from lxml import etree
import time
class daili:
# 1.發(fā)送請(qǐng)求,獲取響應(yīng)
def send_request(self,page):
print("=============正在抓取第{}頁(yè)===========".format(page))
# 目標(biāo)網(wǎng)頁(yè),添加headers參數(shù)
base_url = 'https://www.kuaidaili.com/free/inha/{}/'.format(page)
headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.69 Safari/537.36'}
# 發(fā)送請(qǐng)求:模擬瀏覽器發(fā)送請(qǐng)求,獲取響應(yīng)數(shù)據(jù)
response = requests.get(base_url,headers=headers)
data = response.content.decode()
time.sleep(1)
return data
# 2.解析數(shù)據(jù)
def parse_data(self,data):
# 數(shù)據(jù)轉(zhuǎn)換
html_data = etree.HTML(data)
# 分組數(shù)據(jù)
parse_list = html_data.xpath('//table[@class="table table-bordered table-striped"]/tbody/tr')
return parse_list
# 4.檢測(cè)代理IP
def check_ip(self,proxies_list):
headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.69 Safari/537.36'}
can_use = []
for proxies in proxies_list:
try:
response = requests.get('https://www.baidu.com/',headers=headers,proxies=proxies,timeout=0.1)
if response.status_code == 200:
can_use.append(proxies)
except Exception as e:
print(e)
return can_use
# 5.保存到文件
def save(self,can_use):
file = open('IP.txt', 'w')
for i in range(len(can_use)):
s = str(can_use[i])+ '\n'
file.write(s)
file.close()
# 實(shí)現(xiàn)主要邏輯
def run(self):
proxies_list = []
# 實(shí)現(xiàn)翻頁(yè),我這里只爬取了四頁(yè)(可以修改5所在的數(shù)字)
for page in range(1,5):
data = self.send_request(page)
parse_list = self.parse_data(data)
# 3.獲取數(shù)據(jù)
for tr in parse_list:
proxies_dict = {}
http_type = tr.xpath('./td[4]/text()')
ip_num = tr.xpath('./td[1]/text()')
port_num = tr.xpath('./td[2]/text()')
http_type = ' '.join(http_type)
ip_num = ' '.join(ip_num)
port_num = ' '.join(port_num)
proxies_dict[http_type] = ip_num + ":" + port_num
proxies_list.append(proxies_dict)
print("獲取到的代理IP數(shù)量:",len(proxies_list))
can_use = self.check_ip(proxies_list)
print("能用的代理IP數(shù)量:",len(can_use))
print("能用的代理IP:",can_use)
self.save(can_use)
if __name__ == "__main__":
dl = daili()
dl.run()
啟動(dòng)后的效果如下:
并生成文件:
O了O了?。?!
使用方法
IP保存在文件中了,可有一些小伙伴還不知道怎么去使用?
這里我們需要實(shí)現(xiàn),從文件中隨機(jī)取出一個(gè)IP去訪問網(wǎng)址,用到了random
庫(kù)文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-502240.html
import random
import requests
# 打開文件,換行讀取
f=open("IP.txt","r")
file = f.readlines()
# 遍歷并分別存入列表,方便隨機(jī)選取IP
item = []
for proxies in file:
proxies = eval(proxies.replace('\n','')) # 以換行符分割,轉(zhuǎn)換為dict對(duì)象
item.append(proxies)
proxies = random.choice(item) # 隨機(jī)選取一個(gè)IP
url = 'https://www.baidu.com/'
headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.69 Safari/537.36'}
response = requests.get(url,headers=headers,proxies=proxies)
print(response.status_code) # 輸出狀態(tài)碼 200,表示訪問成功
有講的不對(duì)的地方,希望各位大佬指正!??!,如果有不明白的地方評(píng)論區(qū)留言回復(fù)!兄弟們來(lái)個(gè)點(diǎn)贊收藏有空就更新爬蟲實(shí)戰(zhàn)?。?!
文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-502240.html
到了這里,關(guān)于Python爬蟲實(shí)戰(zhàn)(二):爬取快代理構(gòu)建代理IP池的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!