目 录CONTENT

文章目录

Scrapy 入门_实战爬取快代理免费IP

小张的探险日记
2021-09-07 / 0 评论 / 0 点赞 / 545 阅读 / 2,903 字 / 正在检测是否收录...
温馨提示:
本文最后更新于 2021-12-29,若内容或图片失效,请留言反馈。部分素材来自网络,若不小心影响到您的利益,请联系我们删除。

1.爬虫需求

​ 快代理是一个收费 提供代理ip 的网站,也有提供有免费的 IP,我们的需求是 通过爬虫爬取到本地 写入txt 文件,并通过脚本验证 代理ip 的有效性。 代理ip 的质量参差不齐,必须得验下。

image-20210527230445519

免费 IP 列表

image-20210527230616814

2. 代码实现思路

3 Scrapy 搭建项目

​ 使用 Scrapy 完成,首先搭建一个 Scrapy 项目。

scrapy startProject agentCrawling

cd agentCrawling
# 新建爬虫文件
scrapy genspider agent www.mzitu.com

文件结构如下,main.py 文件为启动文件,如下图。

image-20210527231113463

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 有效性

​ 爬取数据结果。

image-20210527233057736

此段代码来自 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')

image-20210527233625731

经过爬虫验证 快代理 免费的代理IP 有效性 堪忧,并且反爬虫策略,除了限制 快速请求,在一定时间段内 多次请求也会触发 IP 被封。 无奈!!!

0

评论区