1.爬虫需求
快代理是一个收费 提供代理ip 的网站,也有提供有免费的 IP,我们的需求是 通过爬虫爬取到本地 写入txt 文件,并通过脚本验证 代理ip 的有效性。 代理ip 的质量参差不齐,必须得验下。
免费 IP 列表
2. 代码实现思路
3 Scrapy 搭建项目
使用 Scrapy 完成,首先搭建一个 Scrapy 项目。
scrapy startProject agentCrawling
cd agentCrawling
# 新建爬虫文件
scrapy genspider agent www.mzitu.com
文件结构如下,main.py 文件为启动文件,如下图。
from scrapy.cmdline import execute
import os
import sys
"""
启动文件用来代替命令行启动,文件放在项目根目录下
"""
if __name__ == '__main__':
sys.path.append(os.path.dirname(os.path.abspath(__file__)))
execute(['scrapy','crawl','agent'])
4 使用通用爬虫 CrawlSpider
这里使用Scrapy 的通用爬虫 CrawlSpider,实现分页数据的爬取,xpath 选择获取Ip 和 port 数据
免费代理IP 数据 是按时间更新的,肯定是新数据 比较好,所以正则定义只爬取前9页数据。
import scrapy
from scrapy.spiders import CrawlSpider, Rule
from scrapy.linkextractors import LinkExtractor
class AgentSpider(CrawlSpider):
name = 'agent'
allowed_domains = ['kuaidaili.com']
start_urls = ['https://www.kuaidaili.com/free/inha/1/']
# 指定链接提取的规律
rules = (
# allow 设置匹配链接的正则表达式
# callback 设置回调的方法
# follow:是指爬取了之后,是否还继续从该页面提取链接,然后继续爬下去
Rule(LinkExtractor(allow=r'.*/free/inha/\d{1}/$'), callback='parse_item', follow=True),
)
def parse_item(self, response):
for row in response.xpath('//*[@id="list"]/table/tbody').xpath('tr'):
address = row.xpath('td/text()').get() + ":" + row.xpath('td[2]/text()').get()
yield{
'address' : address
}
管道文件中 写入text文件
class AgentcrawlingPipeline:
def process_item(self, item, spider):
with open('address.text',mode='a+',encoding='utf-8') as f:
f.write(item['address'] + '\n')
return item
5 配置爬虫参数及反扒措施
setting.py 配置,快代理 具有反扒措施,访问数据过快,会导致被封IP没有返回,这时候把光猫拔一下,获取到新的ip 即可重新测试, 设置下 如下的反扒措施 即可成功。
ROBOTSTXT_OBEY = False
ITEM_PIPELINES = {
'agentCrawling.pipelines.AgentcrawlingPipeline': 300,
}
# 这里代表:每1s访问一次
DOWNLOAD_DELAY = 1
# 反扒措施
USER_AGENT = 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36'
# 配置请求头
DEFAULT_REQUEST_HEADERS = {
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
# 'Accept-Language': 'en',
}
6 验证代理Ip 有效性
爬取数据结果。
此段代码来自 Ehco Ehco1996 爬墙的少年,不造轮子了,直接用。
主要逻辑,一个是多线程,二是 requests 使用代理IP 请求,通过响应码 判断代理是否有效。
# 验证代理
'''
我们通过这个小脚本来判断
抓取到的ip代理是否可以用!
'''
import requests
# 引入这个库来获得map函数的并发版本
from multiprocessing.dummy import Pool as ThreadPool
alive_ip = []
# 使得map并发!实例化pool对象
pool = ThreadPool()
# 设置并发数量!
pool = ThreadPool(20)
def test_alive(proxy):
'''
一个简单的函数,
来判断通过代理访问百度
筛选通过的代理保存到alive_ip中
'''
global alive_ip
# 设置代理头
proxies = {'http': proxy}
print('正在测试:{}'.format(proxies))
try:
r = requests.get('http://www.baidu.com', proxies=proxies, timeout=3)
if r.status_code == 200:
print('该代理:{}成功存活'.format(proxy))
alive_ip.append(proxy)
except:
print('该代理{}失效!'.format(proxies))
def Out_file(alive_ip=[]):
'''
将符合要求的代理写入文件
'''
with open('alive_ip.txt', 'a+') as f:
for ip in alive_ip:
f.write(ip + '\n')
print('所有存活ip都已经写入文件!')
def test(filename='blank.txt'):
# 循环处理每行文件
with open(filename, 'r') as f:
lines = f.readlines()
# 我们去掉lines每一项后面的\n\r之类的空格
# 生成一个新的列表!
proxys = list(map(lambda x: x.strip(), [y for y in lines]))
# 一行代码解决多线程!
pool.map(test_alive, proxys)
# 将存活的ip写入文件
Out_file(alive_ip)
# 调用函数!
test('address.text')
经过爬虫验证 快代理 免费的代理IP 有效性 堪忧,并且反爬虫策略,除了限制 快速请求,在一定时间段内 多次请求也会触发 IP 被封。 无奈!!!
评论区