精华内容
下载资源
问答
  •  IP代理大师无需安装,直接打开即可使用,无系统残留,是真正的绿色安全软件,软件采用最新编程技术,自动获取最新可用的代理(1小时更新一次哦),是你网站代理的首要选择! 你是否在苦苦寻找一款简单、免费、...
  • Jsoup实现省市区的爬取,突破ip的访问限制,实现动态ip代理,爬取最新的省市区信息
  • IP代理池检测代理可用性

    万次阅读 2019-05-23 19:01:44
    在《基于Scrapy的IP代理池搭建》一文中,我们将从网页爬取到的免费代理IP按照如下格式保存到了Redis的 proxies:unchecked:list 队列中。 同时,为了避免同一代理IP被重复存储,在将代理保存到 proxies:unch...

    目录

    项目代码 

    utils.py

    settings.py

    proxy_queue.py

     check_proxy.py

     运行方法


    《基于Scrapy的IP代理池搭建》一文中,我们将从网页爬取到的免费代理IP按照如下格式保存到了Redis的 proxies:unchecked:list 队列中。

    同时,为了避免同一代理IP被重复存储,在将代理保存到 proxies:unchecked:list 队列之前,会先将其 URL (例如:https://39.98.254.72:3128)保存到 proxies:unchecked:set 集合中用来进行去重校验。

    众所周知,代理IP都是有时效性的。不可避免地,你会发现爬取到 proxies:unchecked:list 队列中的代理大部分都是不可用的,所以在使用代理IP之前还需要对代理IP的可用性进行验证,验证的方法就是:使用代理IP去请求指定URL,根据返回的响应判断代理IP是否可用。

    废话到此为止,接下来呈上验证代理IP可用性的代码,项目完整目录如下。

    项目代码  

    utils.py

     utils.py 是一个工具类,包含了一些常用操作,比如:剔除字符串的首位空白,获取代理IP的URL,更新代理IP的信息。

    # -*- coding: utf-8 -*-
    import logging
    from settings import PROXY_URL_FORMATTER
    
    # 设置日志的输出样式
    logging.basicConfig(level=logging.INFO,
                        format='[%(asctime)-15s] [%(levelname)8s] [%(name)10s ] - %(message)s (%(filename)s:%(lineno)s)',
                        datefmt='%Y-%m-%d %T'
                        )
    logger = logging.getLogger(__name__)
    
    
    # 剔除字符串的首位空格
    def strip(data):
        if data is not None:
            return data.strip()
        return data
    
    # 获取代理IP的url地址
    def _get_url(proxy):
        return PROXY_URL_FORMATTER % {'schema': proxy['schema'], 'ip': proxy['ip'], 'port': proxy['port']}
    
    # 根据请求结果更新代理IP的字段信息
    def _update(proxy, successed=False):
        proxy['used_total'] = proxy['used_total'] + 1
        if successed:
            proxy['continuous_failed'] = 0
            proxy['success_times'] = proxy['success_times'] + 1
        else:
            proxy['continuous_failed'] = proxy['continuous_failed'] + 1

    settings.py

    settings.py 汇聚了整个项目的配置信息。 

    # 指定Redis的主机名和端口
    REDIS_HOST = '172.16.250.238'
    REDIS_PORT = 6379
    REDIS_PASSWORD = 123456
    
    # 保存已经检验的代理的 Redis key 格式化字符串
    PROXIES_REDIS_FORMATTER = 'proxies::{}'
    
    # 保存已经检验的代理
    PROXIES_REDIS_EXISTED = 'proxies::existed'
    
    # 保存未检验代理的Redis key
    PROXIES_UNCHECKED_LIST = 'proxies:unchecked:list'
    
    # 已经存在的未检验HTTP代理和HTTPS代理集合
    PROXIES_UNCHECKED_SET = 'proxies:unchecked:set'
    
    # 最多连续失败几次
    MAX_FAILURE_TIMES = 2
    
    # 代理地址的格式化字符串
    PROXY_URL_FORMATTER = '%(schema)s://%(ip)s:%(port)s'
    
    BASE_HEADERS = {
        'Connection': 'close',
        'Accept': '*/*',
        'Accept-Encoding': 'gzip, deflate, sdch',
        'Accept-Language': 'en-US,en;q=0.9,zh-CN;q=0.8,zh;q=0.7'
    }
    
    USER_AGENT_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"
    ]
    
    # 检验代理可用性的请求地址
    PROXY_CHECK_URLS = {'https': ['https://blog.csdn.net/pengjunlee/article/details/81212250',
                                  'https://blog.csdn.net/pengjunlee/article/details/54974260', 'https://icanhazip.com'],
                        'http': ['http://blog.csdn.net/pengjunlee/article/details/80919833',
                                 'http://blog.csdn.net/pengjunlee/article/details/81589972', 'http://icanhazip.com']}
    

    proxy_queue.py

    proxy_queue.py 定义了两个代理存储队列类:刚刚爬取到的尚未检测过可用性的代理IP队列(UncheckQueue)和已经检测过可用性的代理IP队列(CheckQueue,该队列中的代理IP也需要定时反复检测可用性)。

    # -*- coding: utf-8 -*-
    import json
    from utils import _get_url
    from settings import PROXIES_REDIS_EXISTED, PROXIES_REDIS_FORMATTER, PROXIES_UNCHECKED_LIST, PROXIES_UNCHECKED_SET, \
        MAX_FAILURE_TIMES
    
    """
    Proxy Queue Base Class
    """
    class BaseQueue(object):
    
        def __init__(self, server):
            """Initialize the proxy queue instance
    
            Parameters
            ----------
            server : StrictRedis
                Redis client instance
            """
            self.server = server
    
        def _is_existed(self, proxy):
            """判断当前代理是否已经存在"""
            added = self.server.sadd(PROXIES_REDIS_EXISTED, _get_url(proxy))
            return added == 0
    
        def push(self, proxy):
            """根据检验结果,将代理放入相应队列"""
            if not self._is_existed(proxy) and proxy['continuous_failed'] < MAX_FAILURE_TIMES:
                key = PROXIES_REDIS_FORMATTER.format(proxy['schema'])
                self.server.rpush(key, json.dumps(proxy, ensure_ascii=False))
    
        def pop(self, schema, timeout=0):
            """Pop a proxy"""
            raise NotImplementedError
    
        def __len__(self, schema):
            """Return the length of the queue"""
            raise NotImplementedError
    
    
    class CheckedQueue(BaseQueue):
        """待检测的代理队列"""
    
        def __len__(self, schema):
            """Return the length of the queue"""
            return self.server.llen(PROXIES_REDIS_FORMATTER.format(schema))
    
        def pop(self, schema, timeout=0):
            """从未检测列表弹出一个待检测的代理"""
            if timeout > 0:
                p = self.server.blpop(PROXIES_REDIS_FORMATTER.format(schema), timeout)
                if isinstance(p, tuple):
                    p = p[1]
            else:
                p = self.server.lpop(PROXIES_REDIS_FORMATTER.format(schema))
            if p:
                p = eval(p)
                self.server.srem(PROXIES_REDIS_EXISTED, _get_url(p))
                return p
    
    
    class UncheckedQueue(BaseQueue):
        """已检测的代理队列"""
    
        def __len__(self, schema=None):
            """Return the length of the queue"""
            return self.server.llen(PROXIES_UNCHECKED_LIST)
    
        def pop(self, schema=None, timeout=0):
            """从未检测列表弹出一个待检测的代理"""
            if timeout > 0:
                p = self.server.blpop(PROXIES_UNCHECKED_LIST, timeout)
                if isinstance(p, tuple):
                    p = p[1]
            else:
                p = self.server.lpop(PROXIES_UNCHECKED_LIST)
            if p:
                p = eval(p)
                self.server.srem(PROXIES_UNCHECKED_SET, _get_url(p))
                return p

     check_proxy.py

    使用 OptionParser 模块,通过从命令终端传入不同参数来控制检测不同代理队列的可用性。 

    # encoding=utf-8
    import redis
    from optparse import OptionParser
    import random
    import requests
    from utils import logger, _get_url, _update
    from proxy_queue import CheckedQueue, UncheckedQueue
    from settings import USER_AGENT_LIST, BASE_HEADERS, REDIS_HOST, REDIS_PORT, REDIS_PASSWORD, PROXY_CHECK_URLS
    
    USAGE = "usage: python check_proxy.py [ -c -s <schema>] or [-u]"
    
    parser = OptionParser(USAGE)
    parser.add_option("-c", "--checked", action="store_true", dest="checked", help="check the proxies already checked")
    parser.add_option("-u", "--unchecked", action="store_false", dest="checked", help="check the proxies to be checked")
    parser.add_option("-s", "--schema", action="store", dest="schema", type="choice", choices=['http', 'https'],
                      help="the schema of the proxies to be checked")
    options, args = parser.parse_args()
    
    r = redis.StrictRedis(host=REDIS_HOST, port=REDIS_PORT, password=REDIS_PASSWORD)
    if options.checked:
        schema = options.schema
        if schema is None:
            logger.error("使用 -c 参数时,需要指定 -s 参数!!!")
        proxy_queue = CheckedQueue(r)
    else:
        schema = None
        proxy_queue = UncheckedQueue(r)
    
    # 获取当前待检测队列中代理的数量
    count = proxy_queue.__len__(schema=schema)
    while count > 0:
    
        logger.info("待检测代理数量: " + str(count))
        count = count - 1
    
        # 获取代理
        proxy = proxy_queue.pop(schema=options.schema)
        proxies = {proxy['schema']: _get_url(proxy)}
    
        # 初始化计数字段值
        if "used_total" not in proxy:
            proxy['used_total'] = 0
        if "success_times" not in proxy:
            proxy['success_times'] = 0
        if "continuous_failed" not in proxy:
            proxy['continuous_failed'] = 0
        # 构造请求头
        headers = dict(BASE_HEADERS)
        if 'User-Agent' not in headers.keys():
            headers['User-Agent'] = random.choice(USER_AGENT_LIST)
    
        for url in PROXY_CHECK_URLS[proxy['schema']]:
            try:
                # 使用代理发送请求,获取响应
                response = requests.get(url, headers=headers, proxies=proxies, timeout=5)
            except BaseException:
                logger.info("使用代理< " + _get_url(proxy) + " > 请求 < " + url + " > 结果: 失败 ")
                successed = False
            else:
                if (response.status_code == 200):
                    logger.info("使用代理< " + _get_url(proxy) + " > 请求 < " + url + " > 结果: 成功 ")
                    successed = True
                    break
                else:
                    logger.info("使用代理< " + _get_url(proxy) + " > 请求 < " + url + " > 结果: 失败 ")
                    successed = False
    
        if options.checked:
            # 已检测过的代理,根据检测结果更新代理信息
            _update(proxy, successed=successed)
            # 将代理返还给队列
            proxy_queue.push(proxy)
        elif successed:
            # 首次检测的代理,如果可用直接放入可用队列
            proxy_queue.push(proxy)

     运行方法

     打开命令行终端,执行如下命令开始检测代理IP的可用性:

    python check_proxy.py -u # 检测 proxies:unchecked:list 队列中代理的可用性
    python check_proxy.py -c -s http # 检测 proxies::http 队列中代理的可用性
    python check_proxy.py -c -s https # 检测 proxies::https 队列中代理的可用性

     例如:

    [root@localhost proxy_check]# python3 /usr/local/src/python_projects/proxy_check/check_proxy.py -c -s http
    [2019-05-23 20:15:18] [    INFO] [     utils ] - 待检测代理数量: 437 (check_proxy.py:33)
    [2019-05-23 20:15:23] [    INFO] [     utils ] - 使用代理< http://5.202.192.146:8080 > 请求 < http://blog.csdn.net/pengjunlee/article/details/80919833 > 结果: 失败  (check_proxy.py:58)
    [2019-05-23 20:15:28] [    INFO] [     utils ] - 使用代理< http://5.202.192.146:8080 > 请求 < http://blog.csdn.net/pengjunlee/article/details/81589972 > 结果: 失败  (check_proxy.py:58)
    [2019-05-23 20:15:34] [    INFO] [     utils ] - 使用代理< http://5.202.192.146:8080 > 请求 < http://icanhazip.com > 结果: 失败  (check_proxy.py:58)
    [2019-05-23 20:15:34] [    INFO] [     utils ] - 待检测代理数量: 436 (check_proxy.py:33)
    [2019-05-23 20:15:35] [    INFO] [     utils ] - 使用代理< http://60.217.137.22:8060 > 请求 < http://blog.csdn.net/pengjunlee/article/details/80919833 > 结果: 成功  (check_proxy.py:63)

    Github地址:https://github.com/pengjunlee/proxy_check

    展开全文
  • 基于Scrapy的IP代理池搭建

    万次阅读 多人点赞 2019-05-15 16:27:54
    目录 一、为什么要搭建爬虫代理池 二、搭建思路 ...在众多的网站防爬措施中,有一种是根据ip的访问频率进行限制,即在某一时间段内,当某个ip的访问次数达到一定的阀值时,该ip就会被拉黑、在一段时...

    目录

    一、为什么要搭建爬虫代理池

    二、搭建思路

    三、搭建代理池

    items.py

    kuai_proxy.py

    middlewares.py

    pipelines.py

    settings.py

    utils.py


    一、为什么要搭建爬虫代理池

    在众多的网站防爬措施中,有一种是根据ip的访问频率进行限制,即在某一时间段内,当某个ip的访问次数达到一定的阀值时,该ip就会被拉黑、在一段时间内禁止访问。

    应对的方法有两种:

    1. 降低爬虫的爬取频率,避免IP被限制访问,缺点显而易见:会大大降低爬取的效率。

    2. 搭建一个IP代理池,使用不同的IP轮流进行爬取。

    二、搭建思路

    1、从代理网站(如:西刺代理、快代理、云代理、无忧代理)爬取代理IP;

    2、验证代理IP的可用性(使用代理IP去请求指定URL,根据响应验证代理IP是否生效);

    3、将可用的代理IP保存到数据库;

    《Python爬虫代理池搭建》一文中我们已经使用Python的 requests 模块简单实现了一个IP代理池搭建,但是爬取速度较慢。由于西刺代理、快代理和云代理等网站需要爬取的IP代理列表页多达上千页,使用此种方法来爬取其实并不适合。

    本文将以快代理网站的IP代理爬取为例,示例如何使用 Scrapy-Redis 来爬取代理IP。

    三、搭建代理池

    scrapy 项目的目录结构如下:

    items.py

    # -*- coding: utf-8 -*-
    import re
    import scrapy
    from proxy_pool.settings import PROXY_URL_FORMATTER
    
    schema_pattern = re.compile(r'http|https$', re.I)
    ip_pattern = re.compile(r'^([0-9]{1,3}.){3}[0-9]{1,3}$', re.I)
    port_pattern = re.compile(r'^[0-9]{2,5}$', re.I)
    
    
    class ProxyPoolItem(scrapy.Item):
        # define the fields for your item here like:
        # name = scrapy.Field()
        '''
            {
                "schema": "http", # 代理的类型
                "ip": "127.0.0.1", # 代理的IP地址
                "port": "8050", # 代理的端口号
                "original":"西刺代理",
                "used_total": 11, # 代理的使用次数
                "success_times": 5, # 代理请求成功的次数
                "continuous_failed": 3, # 使用代理发送请求,连续失败的次数
                "created_time": "2018-05-02" # 代理的爬取时间
            }
        '''
        schema = scrapy.Field()
        ip = scrapy.Field()
        port = scrapy.Field()
        original = scrapy.Field()
        used_total = scrapy.Field()
        success_times = scrapy.Field()
        continuous_failed = scrapy.Field()
        created_time = scrapy.Field()
    
        # 检查IP代理的格式是否正确
        def _check_format(self):
            if self['schema'] is not None and self['ip'] is not None and self['port'] is not None:
                if schema_pattern.match(self['schema']) and ip_pattern.match(self['ip']) and port_pattern.match(
                        self['port']):
                    return True
            return False
    
        # 获取IP代理的url
        def _get_url(self):
            return PROXY_URL_FORMATTER % {'schema': self['schema'], 'ip': self['ip'], 'port': self['port']}

    kuai_proxy.py

    # -*- coding: utf-8 -*-
    import re
    import time
    import scrapy
    from proxy_pool.utils import strip, logger
    from proxy_pool.items import ProxyPoolItem
    
    
    class KuaiProxySpider(scrapy.Spider):
        name = 'kuai_proxy'
        allowed_domains = ['kuaidaili.com']
        start_urls = ['https://www.kuaidaili.com/free/inha/1/', 'https://www.kuaidaili.com/free/intr/1/']
    
        def parse(self, response):
            logger.info('正在爬取:< ' + response.request.url + ' >')
            tr_list = response.css("div#list>table>tbody tr")
            for tr in tr_list:
                ip = tr.css("td[data-title='IP']::text").get()
                port = tr.css("td[data-title='PORT']::text").get()
                schema = tr.css("td[data-title='类型']::text").get()
                if schema.lower() == "http" or schema.lower() == "https":
                    item = ProxyPoolItem()
                    item['schema'] = strip(schema).lower()
                    item['ip'] = strip(ip)
                    item['port'] = strip(port)
                    item['original'] = '快代理'
                    item['created_time'] = time.strftime('%Y-%m-%d', time.localtime(time.time()))
                    if item._check_format():
                        yield item
            next_page = response.xpath("//a[@class='active']/../following-sibling::li/a/@href").get()
            if next_page is not None:
                next_url = 'https://www.kuaidaili.com' + next_page
                yield scrapy.Request(next_url)

    middlewares.py

    # -*- coding: utf-8 -*-
    
    import random
    from proxy_pool.utils import logger
    
    
    # 随机选择 IP 代理下载器中间件
    class RandomProxyMiddleware(object):
    
        # 从 settings 的 PROXIES 列表中随机选择一个作为代理
        def process_request(self, request, spider):
            proxy = random.choice(spider.settings['PROXIES'])
            request.meta['proxy'] = proxy
            return None
    
    
    # 随机选择 User-Agent 的下载器中间件
    class RandomUserAgentMiddleware(object):
        def process_request(self, request, spider):
            # 从 settings 的 USER_AGENTS 列表中随机选择一个作为 User-Agent
            user_agent = random.choice(spider.settings['USER_AGENT_LIST'])
            request.headers['User-Agent'] = user_agent
            return None
    
        def process_response(self, request, response, spider):
            # 验证 User-Agent 设置是否生效
            logger.info("headers ::> User-Agent = " + str(request.headers['User-Agent'], encoding="utf8"))
            return response

    pipelines.py

    # -*- coding: utf-8 -*-
    
    import json
    import redis
    from proxy_pool.settings import REDIS_HOST,REDIS_PORT,REDIS_PARAMS,PROXIES_UNCHECKED_LIST,PROXIES_UNCHECKED_SET
    
    server = redis.StrictRedis(host=REDIS_HOST, port=REDIS_PORT,password=REDIS_PARAMS['password'])
    
    class ProxyPoolPipeline(object):
    
        # 将可用的IP代理添加到代理池队列
        def process_item(self, item, spider):
            if not self._is_existed(item):
                server.rpush(PROXIES_UNCHECKED_LIST, json.dumps(dict(item),ensure_ascii=False))
    
        # 检查IP代理是否已经存在
        def _is_existed(self,item):
            added = server.sadd(PROXIES_UNCHECKED_SET, item._get_url())
            return added == 0

    settings.py

    # -*- coding: utf-8 -*-
    BOT_NAME = 'proxy_pool'
    
    SPIDER_MODULES = ['proxy_pool.spiders']
    NEWSPIDER_MODULE = 'proxy_pool.spiders'
    
    # 保存未检验代理的Redis key
    PROXIES_UNCHECKED_LIST = 'proxies:unchecked:list'
    
    # 已经存在的未检验HTTP代理和HTTPS代理集合
    PROXIES_UNCHECKED_SET = 'proxies:unchecked:set'
    
    # 代理地址的格式化字符串
    PROXY_URL_FORMATTER = '%(schema)s://%(ip)s:%(port)s'
    
    # 通用请求头字段
    DEFAULT_REQUEST_HEADERS = {
        'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8',
        'Accept-Encoding': 'gzip, deflate, br',
        'Accept-Language': 'zh-CN,zh;q=0.9,en;q=0.8,zh-TW;q=0.7',
        'Connection': 'keep-alive'
    }
    
    # 请求太频繁会导致 503 ,在此设置 5 秒请求一次
    DOWNLOAD_DELAY = 5  # 250 ms of delay
    
    USER_AGENT_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"
    ]
    
    # Obey robots.txt rules
    ROBOTSTXT_OBEY = False
    
    # Enable or disable downloader middlewares
    # See https://doc.scrapy.org/en/latest/topics/downloader-middleware.html
    DOWNLOADER_MIDDLEWARES = {
        'proxy_pool.middlewares.RandomUserAgentMiddleware': 543,
        #   'proxy_pool.middlewares.RandomProxyMiddleware': 544,
    }
    
    ITEM_PIPELINES = {
        'proxy_pool.pipelines.ProxyPoolPipeline': 300,
    }
    
    PROXIES = [
        "https://171.13.92.212:9797",
        "https://164.163.234.210:8080",
        "https://143.202.73.219:8080",
        "https://103.75.166.15:8080"
    ]
    
    ######################################################
    ##############下面是Scrapy-Redis相关配置################
    ######################################################
    
    # 指定Redis的主机名和端口
    REDIS_HOST = '172.16.250.238'
    REDIS_PORT = 6379
    REDIS_PARAMS = {'password': '123456'}
    
    # 调度器启用Redis存储Requests队列
    SCHEDULER = "scrapy_redis.scheduler.Scheduler"
    
    # 确保所有的爬虫实例使用Redis进行重复过滤
    DUPEFILTER_CLASS = "scrapy_redis.dupefilter.RFPDupeFilter"
    
    # 将Requests队列持久化到Redis,可支持暂停或重启爬虫
    SCHEDULER_PERSIST = True
    
    # Requests的调度策略,默认优先级队列
    SCHEDULER_QUEUE_CLASS = 'scrapy_redis.queue.PriorityQueue'

    utils.py

    # -*- coding: utf-8 -*-
    import logging
    
    # 设置日志输出格式
    logging.basicConfig(level=logging.INFO,
                        format='[%(asctime)-15s] [%(levelname)8s] [%(name)10s ] - %(message)s (%(filename)s:%(lineno)s)',
                        datefmt='%Y-%m-%d %T'
                        )
    logger = logging.getLogger(__name__)
    
    # Truncate header and tailer blanks
    def strip(data):
        if data is not None:
            return data.strip()
        return data

     

    展开全文
  • 爬虫(第一篇) IP代理

    千次阅读 2021-01-27 16:31:01
    搞虫子的都知道,IP代理是必要的方法,为什么?这个大家知道就好了,最近写了个IP代理池,给大家围观一下:开始。 首先咱们找到一个免费的IP代理网站,读取人家的数据,但是注意了,注意频率 别把人家给搞崩了 第...

    搞虫子的都知道,IP代理是必要的方法,为什么?这个大家知道就好了,最近写了个IP代理池,给大家围观一下:开始。

    首先咱们找到一个免费的IP代理网站,读取人家的数据,但是注意了,注意频率 别把人家给搞崩了

    本服务采用的依赖:Springboot、apache util、jsoup、fastjson、Redis 等

    第一:线程池,多个线程检测

    package com.*.util.thread;
    
    import org.apache.log4j.Logger;
    
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    
    /***
     * *
     * 类名称:		CustomExecutorService   
     * 类描述:		线程池配置   
     * 创建人:		
     * 创建时间:	2014-11-21 下午4:45:26   
     * 修改人:		
     * 修改时间:	2016-10-21 下午4:45:26   
     * 修改备注:   
     * @version	1.1
     */
    public class CustomExecutorService {
    
    	private static Logger log = Logger.getLogger( CustomExecutorService.class ) ;
    	
    	private static ExecutorService executorService; 		// 线程池
    	private static final int POOL_MULTIPLE = 0x0000000a ; 	// 线程池中单个CPU分配工作线程的数目(十六进制)
    	private static CustomExecutorService instance;
    
    	private CustomExecutorService() {
    		// 创建一个线程池                            可用处理器数*线程池工作数
    		executorService = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors() * POOL_MULTIPLE * 5 );
    	}
    	
    	/****
    	 * 返回线程池
    	 * @return
    	 */
    	public static ExecutorService getExecutorService(){
    		return executorService ;
    	}
    
    	/***
    	 * 一次调用就可以了,很多地方其实不再需要再次调用,在系统启动的时候调用一次就可以了
    	 * @return
    	 */
    	public synchronized static CustomExecutorService getInstance() {
    		if (instance == null) {
    			instance = new CustomExecutorService();
    			log.info( "Thread pool instance success" ) ;
    		}
    		return instance;
    	}
    	
    	/****
    	 * 一次调用就可以了,在系统关闭的时候调用一次就可以了
    	 */
    	public static void destory() {
    		log.info( "Thread pool shutdown ..." ) ;
    		executorService.shutdown() ;
    	}
    
    	/****
    	 * 具体执行线程的调用
    	 * @param thread
    	 */
    	public static void execute( Runnable thread ) {
    		if( executorService != null ){
    			executorService.execute(thread);
    		}else{
    			CustomExecutorService.getInstance() ;
    			try{ Thread.sleep( 1 ); }catch (Exception e){}
    			execute( thread ) ;
    			log.error( "Thread pool haven't instance,please instance Thread pool." ) ;
    		}
    	}
    	
    	public static void main(String[] args) {
    		CustomExecutorService.getInstance() ;		//线程池初始化 --- 系统启动时调用一次就ok
    		CustomExecutorService.execute( new Thread() ) ;		
    		CustomExecutorService.destory() ;
    	}
    
    }
    

    第二:定时器,定时处理Redis中无效的IP

    package *.*.*.ipproxy;
    
    import com.alibaba.fastjson.JSONObject;
    import com.*.util.thread.CustomExecutorService;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.context.annotation.Lazy;
    import org.springframework.data.redis.core.RedisTemplate;
    import org.springframework.scheduling.annotation.EnableScheduling;
    import org.springframework.scheduling.annotation.Scheduled;
    import org.springframework.stereotype.Component;
    
    import java.util.List;
    
    /**
     * @Date 创建时间: 2021-01-18 15:58
     * @Author 作者姓名: WuNengDeShiXiong
     * @Version 1.0
     * @Copyright Copyright by
     * @Direction 类说明
     */
    @Component
    @Lazy(value = false)
    @EnableScheduling
    public class IpSourceValid {
    
        private final static Logger logger = LoggerFactory.getLogger( IpSourceValid.class ) ;
    
        @Autowired
        private RedisTemplate redisTemplate;
    
        /****
         * 已有的代理池,则需要30秒刷新一次,不可用的IP代理池、全部丢弃
         */
        @Scheduled(cron = "0 * * * * ?")
        void update() {
            logger.info( " redis IP代理池检测开始 ....................."  );
            List<String> range = redisTemplate.opsForList().range("ip", 0, -1);
            for (String ipInfoJson : range) {
                //线程池检测-代理IP池-有效的IP有哪些
                CustomExecutorService.execute(new Thread() {
                    @Override
                    public void run() {
                        IPInfo ipInfo = JSONObject.parseObject( ipInfoJson , IPInfo.class ) ;
                        //使用时-要求偏低,不可用时从Redis删除
                        Boolean useLess = IpInvalidUtils.useless( ipInfo.getIp() , Integer.parseInt(ipInfo.getPort() ) , false ) ;
                        if ( useLess ) {
                            logger.info( " {} 从redis移除" , ipInfoJson );
                            redisTemplate.opsForList().remove("ip", 0, ipInfoJson );
                        }
                    }
                }) ;
            }
            logger.info( " redis IP代理池检测结束 ....................."  );
        }
        
    }
    

    第三: 从开源网站读取的IP转换成对象

    package *.*.*.ipproxy;
    
    import org.jsoup.select.Elements;
    
    import java.io.Serializable;
    
    /**
     * @Date 创建时间: 2021-01-14 11:56
     * @Author 作者姓名: WuNengDeShiXiong
     * @Version 1.0
     * @Copyright Copyright by
     * @Direction 类说明
     */
    public class IPInfo implements Serializable {
    
        private String ip ;
        private String port ;
        private String city ;
        private String type ;
        private String validTime ;
        private String source ;
    
        public IPInfo(){}
    
        public IPInfo(Elements tdChilds){
            if ( tdChilds != null  && tdChilds.size() > 1 ) {
                this.ip = tdChilds.get(0).text() ;
                this.port = tdChilds.get(1).text() ;
                this.city = "中国" + tdChilds.get(2).text() ;
                this.type = tdChilds.get(3).text() ;
                this.validTime = tdChilds.get(4).text() ;
            }
        }
    
        get set ......
    }
    

     第四:使用简单的java连接使用代理去访问牛皮的网站,此处使用的是QQ的地址,响应速度快

    package *.*.*.ipproxy;
    
    import org.jsoup.Connection;
    import org.jsoup.Jsoup;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    
    /**
     * @Date 创建时间: 2021-01-14 10:22
     * @Author 作者姓名: WuNengDeShiXiong
     * @Version 1.0
     * @Copyright Copyright by
     * @Direction 类说明       验证代理的IP与端口
     */
    public class IpInvalidUtils {
    
        private final static Logger logger = LoggerFactory.getLogger( IpSourceValid.class ) ;
        private final static String valid_url = "https://graph.qq.com/oauth2.0" ;      //自定义一个网站地址就可以了,百度、腾讯、阿里能够访问即可,返回信息越少越好
    
        private final static String User_Agent = "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4240.183 Safari/537.36" ;
    
        private final static int connent_timeout_normal = 2000 ;
        private final static int connent_timeout_slow = 5000 ;
    
        /****
         * 内部代理方法
         * @param ip
         * @param port
         * @return
         */
        public static boolean useless( String ip , Integer port){
            return useless(  ip ,  port , true ) ;
        }
    
        /****
         * 验证IP、端口 是否可用
         * @param ip
         * @param port
         * @return 无效的ip 返回true 有效的ip返回false
         */
        public static boolean useless( String ip , Integer port, Boolean high) {
            Connection jsoupConn = null;
            boolean requestIsFail = true ;
            try {
                //创建请求
                jsoupConn = Jsoup.connect( valid_url ).userAgent( User_Agent ) ;
                jsoupConn.proxy( ip , port ) ;
                if( high ) {
                    //要求高-则检测时间必须在2秒内响应
                    jsoupConn.timeout( connent_timeout_normal );     // timeout:设置连接主机超时(单位:毫秒)
                }else{
                    //要求低-则检测时间必须在响应
                    jsoupConn.timeout( connent_timeout_slow );       // timeout:设置连接主机超时(单位:毫秒)
                }
                //解析请求信息 能够解析到请求结果的一律认为访问成功
                Connection.Response resp = jsoupConn.execute();
                if ( resp.statusCode() > 0 ) {
                    //String body = jsoupConn.get().getElementsByTag("body").html();
                    requestIsFail = false ;
                }
            } catch (Exception e) {
                logger.error( "数据识别 此IP: {} 端口:{} 失败的原因:{}" , ip , port , e.getMessage() );
            }
            return requestIsFail ;
        }
    
    
    }

    第五步:咱们就要定时去网站取数据了

    package *.*.*.ipproxy;
    
    import com.alibaba.fastjson.JSON;
    import com.*.util.thread.CustomExecutorService;
    import org.apache.commons.lang3.StringUtils;
    import org.jsoup.Jsoup;
    import org.jsoup.nodes.Document;
    import org.jsoup.nodes.Element;
    import org.jsoup.select.Elements;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.context.annotation.Lazy;
    import org.springframework.data.redis.core.RedisTemplate;
    import org.springframework.scheduling.annotation.EnableScheduling;
    import org.springframework.scheduling.annotation.Scheduled;
    import org.springframework.stereotype.Component;
    
    import java.io.IOException;
    import java.util.List;
    
    /**
     * @Date 创建时间: 2021-01-14 10:21
     * @Author 作者姓名: WuNengDeShiXiong
     * @Version 1.0
     * @Copyright Copyright by
     * @Direction 类说明       定时取一个免费的源,然后对免费的源获取的IP做数据检查
     *                        多线程获取-然后做数据检测
     */
    @Component
    @Lazy(value = false)
    @EnableScheduling
    public class UpdateIpSource1 {
    
        private final static Logger logger = LoggerFactory.getLogger( UpdateIpSource1.class ) ;
    
        @Autowired
        private RedisTemplate redisTemplate;
    
        /***
         * 获取可用的IP代理池,10分钟运行一次
         */
        @Scheduled(cron = "0 */10 * * * ?")
        public void ips() {
            String prefix = "http://www.66ip.cn/areaindex_" ;
            String suxfix = "/1.html" ;
            StringBuilder url = null ;
           //只取前5页的有效数据
           for(int i=1 ;i<5 ;i++){
               url = new StringBuilder( prefix ).append( i ).append( suxfix ) ;
               parseUrl( url.toString() ) ;
           }
        }
    
        /****
         * 解析指定地址,然后从地址内获取IP、端口;
         * @param url
         */
        public void parseUrl( String url ){
            try {
                //Document document = Jsoup.connect( "http://www.66ip.cn/areaindex_1/1.html" ).timeout(3000).get();
                Document document = Jsoup.connect( url ).timeout(3000).get();
                Elements tags = document.select("table > tbody > tr");
                for (Element element : tags) {
                    //取得ip地址节点、端口号节点
                    Elements tdChilds = element.select("td");
                    logger.info( " 准备验证数据 {}    ------source1------" , tdChilds.text() );
                    IPInfo ipInfo = new IPInfo( tdChilds ) ;
                    ipInfo.setSource("1");
                    redisHandler( ipInfo ) ;
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    
        /*****
         * 验证读取到的IP地址是否有效,并且写入到Redis服务
         * @param ipInfo
         */
        public void redisHandler( IPInfo ipInfo ){
            //第一步检测数据有效性,且只有有效数据才做数据检测
            if ( ipInfo != null && StringUtils.isNotBlank( ipInfo.getIp() ) && StringUtils.isNotBlank( ipInfo.getPort() ) ) {
                try {
                    Integer.parseInt(ipInfo.getPort() ) ;
                }catch (Exception e){
                    logger.info("端口号为非数字,丢弃请求.................------source1------");
                    return ;
                }
                //第二步 采用多线程对IP端口做代理检测
                CustomExecutorService.execute(new Thread(){
                    @Override
                    public void run() {
                        Boolean useLess = IpInvalidUtils.useless( ipInfo.getIp() , Integer.parseInt(ipInfo.getPort() )) ;
                        if ( ! useLess ) {
                            String ipInfoJson = JSON.toJSONString( ipInfo ) ;
                            //将有效的数据移动到最左边,第一位
                            List<String> range = redisTemplate.opsForList().range("ip", 0, -1 );
                            if ( ! range.contains( ipInfoJson ) ) {
                                logger.info( " {} 有效,开始-存进redis {}    ------source1------" ,  ipInfoJson );
                                if (redisTemplate.opsForList().size("ip") > 1000) {
                                    redisTemplate.opsForList().rightPopAndLeftPush("ip", ipInfoJson);
                                }else{
                                    redisTemplate.opsForList().leftPush("ip", ipInfoJson );
                                }
                            }
                        }
                    }
                }) ;
            }
        }
    
    }
    

    好了,今天的代理池获取就完成了。引用的Maven请看下文  Springboot基础包就不发了

    <!-- https://mvnrepository.com/artifact/com.alibaba/fastjson -->
    <dependency>
    	<groupId>com.alibaba</groupId>
    	<artifactId>fastjson</artifactId>
    	<version>1.2.47</version>
    </dependency>
    
    <!-- https://mvnrepository.com/artifact/org.jsoup/jsoup -->
    <dependency>
    	<groupId>org.jsoup</groupId>
    	<artifactId>jsoup</artifactId>
    	<version>1.11.3</version>
    </dependency>
    
    
    apache的Utils包就不贴了,大家都用

     

    展开全文
  • 红苹果IP代理软件

    2013-07-15 16:35:38
    用于获取代理IP的小工具,用于免费获取代理IP地址,效果超级好
  • ip代理

    万次阅读 2020-04-25 23:44:21
    为什么会出现IP被封 网站为了防止被爬取,会有反爬机制,对于同一个IP地址的大量...采用代理IP并轮换 设置访问时间间隔 如何获取代理IP地址 从该网站获取: https://www.xicidaili.com/ inspect -> 鼠标定位:...

    为什么会出现IP被封

    网站为了防止被爬取,会有反爬机制,对于同一个IP地址的大量同类型的访问,会封锁IP,过一段时间后,才能继续访问

    如何应对IP被封的问题

    有几种套路:

    1. 修改请求头,模拟浏览器(而不是代码去直接访问)去访问
    2. 采用代理IP并轮换
    3. 设置访问时间间隔

    如何获取代理IP地址

    • 从该网站获取: https://www.xicidaili.com/
    • inspect -> 鼠标定位:
    • 要获取的代理IP地址,属于class = "odd"标签的内容:代码如下,获取的代理IP保存在proxy_ip_list列表中
    # show your code
    
    # 案例代码
    from bs4 import BeautifulSoup
    import requests
    import time
    
    def open_proxy_url(url):
        user_agent = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.119 Safari/537.36'
        headers = {'User-Agent': user_agent}
        try:
            r = requests.get(url, headers = headers, timeout = 20)
            r.raise_for_status()
            r.encoding = r.apparent_encoding
            return(r.text)
        except:
            print('无法访问网页' + url)
    
    
    def get_proxy_ip(response):
        proxy_ip_list = []
        soup = BeautifulSoup(response, 'html.parser')
        proxy_ips  = soup.select('.odd')#选择标签
        for proxy_ip in proxy_ips:
            ip = proxy_ip.select('td')[1].text
            port = proxy_ip.select('td')[2].text
            protocol = proxy_ip.select('td')[5].text
            if protocol in ('HTTP','HTTPS'):
                proxy_ip_list.append(f'{protocol}://{ip}:{port}')
        return proxy_ip_list
    
    if __name__ == '__main__':
        proxy_url = 'https://www.xicidaili.com/'
        text = open_proxy_url(proxy_url)
        proxy_ip_filename = 'proxy_ip.txt'
        with open(proxy_ip_filename, 'w') as f:
            f.write(text)
        text = open(proxy_ip_filename, 'r').read()
        proxy_ip_list = get_proxy_ip(text)
        print(proxy_ip_list)
    
    # text
    
    

    获取如下数据:

    获取到代理IP地址后,发现数据缺失很多,再仔细查看elements,发现有些并非class = “odd”,而是…,这些数据没有被获取
    class = "odd"奇数的结果,而没有class = "odd"的是偶数的结果
    在这里插入图片描述

    通过bs4的find_all(‘tr’)来获取所有IP:

    # show your code
    
    def get_proxy_ip(response):
        proxy_ip_list = []
        soup = BeautifulSoup(response, 'html.parser')
        proxy_ips = soup.find(id = 'ip_list').find_all('tr')
        for proxy_ip in proxy_ips:
            if len(proxy_ip.select('td')) >=8:
                ip = proxy_ip.select('td')[1].text
                port = proxy_ip.select('td')[2].text
                protocol = proxy_ip.select('td')[5].text
                if protocol in ('HTTP','HTTPS','http','https'):
                    proxy_ip_list.append(f'{protocol}://{ip}:{port}')
        return proxy_ip_list
    

    使用代理

    • proxies的格式是一个字典:
    • {‘http’: ‘http://IP:port‘,‘https’:'https://IP:port‘}
    • 把它直接传入requests的get方法中即可
    • web_data = requests.get(url, headers=headers, proxies=proxies)
    # show your code
    
    def open_url_using_proxy(url, proxy):
        user_agent = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.119 Safari/537.36'
        headers = {'User-Agent': user_agent}
        proxies = {}
        if proxy.startswith('HTTPS'):
            proxies['https'] = proxy
        else:
            proxies['http'] = proxy
        try:
            r = requests.get(url, headers = headers, proxies = proxies, timeout = 10)
            r.raise_for_status()
            r.encoding = r.apparent_encoding
            return (r.text, r.status_code)
        except:
            print('无法访问网页' + url)
            return False
    url = 'http://www.baidu.com'
    text = open_url_using_proxy(url, proxy_ip_list[0])
    
    无法访问网页http://www.baidu.com
    

    确认代理IP地址有效性

    • 无论是免费还是收费的代理网站,提供的代理IP都未必有效,我们应该验证一下,有效后,再放入我们的代理IP池中,以下通过几种方式:访问网站,得到的返回码是200真正的访问某些网站,获取title等,验证title与预计的相同访问某些可以提供被访问IP的网站,类似于“查询我的IP”的网站,查看返回的IP地址是什么验证返回码
    # show your code
    
    def check_proxy_avaliability(proxy):
        url = 'http://www.baidu.com'
        result = open_url_using_proxy(url, proxy)
        VALID_PROXY = False
        if result:
            text, status_code = result
            if status_code == 200:
                print('有效代理IP: ' + proxy)
            else:
                print('无效代理IP: ' + proxy)
    

    改进:确认网站title

    # show you code
    
    def check_proxy_avaliability(proxy):
        url = 'http://www.baidu.com'
        text, status_code = open_url_using_proxy(url, proxy)
        VALID = False
        if status_code == 200:
            if r_title:
                if r_title[0] == '<title>百度一下,你就知道</title>':
                    VALID = True
        if VALID:
            print('有效代理IP: ' + proxy)
        else:
            print('无效代理IP: ' + proxy)
    

    完整代码

    from bs4 import BeautifulSoup
    import requests
    import re
    import json
    
    
    def open_proxy_url(url):
        user_agent = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.119 Safari/537.36'
        headers = {'User-Agent': user_agent}
        try:
            r = requests.get(url, headers = headers, timeout = 10)
            r.raise_for_status()
            r.encoding = r.apparent_encoding
            return r.text
        except:
            print('无法访问网页' + url)
    
    
    def get_proxy_ip(response):
        proxy_ip_list = []
        soup = BeautifulSoup(response, 'html.parser')
        proxy_ips = soup.find(id = 'ip_list').find_all('tr')
        for proxy_ip in proxy_ips:
            if len(proxy_ip.select('td')) >=8:
                ip = proxy_ip.select('td')[1].text
                port = proxy_ip.select('td')[2].text
                protocol = proxy_ip.select('td')[5].text
                if protocol in ('HTTP','HTTPS','http','https'):
                    proxy_ip_list.append(f'{protocol}://{ip}:{port}')
        return proxy_ip_list
    
    
    def open_url_using_proxy(url, proxy):
        user_agent = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.119 Safari/537.36'
        headers = {'User-Agent': user_agent}
        proxies = {}
        if proxy.startswith(('HTTPS','https')):
            proxies['https'] = proxy
        else:
            proxies['http'] = proxy
    
        try:
            r = requests.get(url, headers = headers, proxies = proxies, timeout = 10)
            r.raise_for_status()
            r.encoding = r.apparent_encoding
            return (r.text, r.status_code)
        except:
            print('无法访问网页' + url)
            print('无效代理IP: ' + proxy)
            return False
    
    
    def check_proxy_avaliability(proxy):
        url = 'http://www.baidu.com'
        result = open_url_using_proxy(url, proxy)
        VALID_PROXY = False
        if result:
            text, status_code = result
            if status_code == 200:
                r_title = re.findall('<title>.*</title>', text)
                if r_title:
                    if r_title[0] == '<title>百度一下,你就知道</title>':
                        VALID_PROXY = True
            if VALID_PROXY:
                check_ip_url = 'https://jsonip.com/'
                try:
                    text, status_code = open_url_using_proxy(check_ip_url, proxy)
                except:
                    return
    
                print('有效代理IP: ' + proxy)
                with open('valid_proxy_ip.txt','a') as f:
                    f.writelines(proxy)
                try:
                    source_ip = json.loads(text).get('ip')
                    print(f'源IP地址为:{source_ip}')
                    print('='*40)
                except:
                    print('返回的非json,无法解析')
                    print(text)
        else:
            print('无效代理IP: ' + proxy)
    
    
    if __name__ == '__main__':
        proxy_url = 'https://www.xicidaili.com/'
        proxy_ip_filename = 'proxy_ip.txt'
        text = open(proxy_ip_filename, 'r').read()
        proxy_ip_list = get_proxy_ip(text)
        for proxy in proxy_ip_list:
            check_proxy_avaliability(proxy)
    
    无法访问网页http://www.baidu.com
    无效代理IP: HTTP://113.194.28.11:9999
    无效代理IP: HTTP://113.194.28.11:9999
    无法访问网页http://www.baidu.com
    无效代理IP: HTTP://113.195.168.115:48888
    无效代理IP: HTTP://113.195.168.115:48888
    无法访问网页http://www.baidu.com
    无效代理IP: HTTP://118.113.247.115:9999
    无效代理IP: HTTP://118.113.247.115:9999
    无法访问网页http://www.baidu.com
    无效代理IP: HTTP://60.167.112.236:1133
    无效代理IP: HTTP://60.167.112.236:1133
    无法访问网页http://www.baidu.com
    无效代理IP: HTTP://101.132.190.101:80
    无效代理IP: HTTP://101.132.190.101:80
    无法访问网页http://www.baidu.com
    无效代理IP: HTTP://111.222.141.127:8118
    无效代理IP: HTTP://111.222.141.127:8118
    无法访问网页http://www.baidu.com
    无效代理IP: HTTPS://117.88.177.101:3000
    无效代理IP: HTTPS://117.88.177.101:3000
    无法访问网页http://www.baidu.com
    无效代理IP: HTTP://183.166.136.144:8888
    无效代理IP: HTTP://183.166.136.144:8888
    无法访问网页http://www.baidu.com
    无效代理IP: HTTP://27.208.231.100:8060
    无效代理IP: HTTP://27.208.231.100:8060
    无法访问网页http://www.baidu.com
    无效代理IP: HTTP://123.169.99.177:9999
    无效代理IP: HTTP://123.169.99.177:9999
    无法访问网页http://www.baidu.com
    无效代理IP: HTTP://119.84.84.185:12345
    无效代理IP: HTTP://119.84.84.185:12345
    无法访问网页http://www.baidu.com
    无效代理IP: HTTPS://114.99.54.65:8118
    无效代理IP: HTTPS://114.99.54.65:8118
    无法访问网页http://www.baidu.com
    无效代理IP: HTTPS://119.4.13.26:1133
    无效代理IP: HTTPS://119.4.13.26:1133
    无法访问网页http://www.baidu.com
    无效代理IP: HTTP://58.253.158.177:9999
    无效代理IP: HTTP://58.253.158.177:9999
    无法访问网页http://www.baidu.com
    无效代理IP: HTTP://114.223.208.165:8118
    无效代理IP: HTTP://114.223.208.165:8118
    无法访问网页http://www.baidu.com
    无效代理IP: HTTP://112.84.73.53:9999
    无效代理IP: HTTP://112.84.73.53:9999
    无法访问网页http://www.baidu.com
    无效代理IP: HTTP://221.237.37.137:8118
    无效代理IP: HTTP://221.237.37.137:8118
    无法访问网页http://www.baidu.com
    无效代理IP: HTTPS://117.45.139.84:9006
    无效代理IP: HTTPS://117.45.139.84:9006
    无法访问网页http://www.baidu.com
    无效代理IP: HTTPS://171.35.86.72:8118
    无效代理IP: HTTPS://171.35.86.72:8118
    无法访问网页http://www.baidu.com
    无效代理IP: HTTP://49.235.246.24:8118
    无效代理IP: HTTP://49.235.246.24:8118
    无法访问网页http://www.baidu.com
    无效代理IP: HTTP://112.95.205.138:8888
    无效代理IP: HTTP://112.95.205.138:8888
    无法访问网页http://www.baidu.com
    无效代理IP: HTTP://14.115.105.104:808
    无效代理IP: HTTP://14.115.105.104:808
    无法访问网页http://www.baidu.com
    无效代理IP: HTTP://60.191.11.249:3128
    无效代理IP: HTTP://60.191.11.249:3128
    无法访问网页http://www.baidu.com
    无效代理IP: HTTP://14.115.104.119:808
    无效代理IP: HTTP://14.115.104.119:808
    无法访问网页http://www.baidu.com
    无效代理IP: HTTPS://121.13.252.60:41564
    无效代理IP: HTTPS://121.13.252.60:41564
    无法访问网页http://www.baidu.com
    无效代理IP: HTTP://112.95.205.135:9000
    无效代理IP: HTTP://112.95.205.135:9000
    无法访问网页http://www.baidu.com
    无效代理IP: HTTPS://125.123.139.19:9000
    无效代理IP: HTTPS://125.123.139.19:9000
    无法访问网页https://jsonip.com/
    无效代理IP: HTTP://218.27.204.240:8000
    无法访问网页http://www.baidu.com
    无效代理IP: HTTPS://116.204.142.62:8080
    无效代理IP: HTTPS://116.204.142.62:8080
    无法访问网页http://www.baidu.com
    无效代理IP: HTTPS://60.191.11.229:3128
    无效代理IP: HTTPS://60.191.11.229:3128
    无法访问网页http://www.baidu.com
    无效代理IP: HTTP://163.125.71.198:9999
    无效代理IP: HTTP://163.125.71.198:9999
    无法访问网页http://www.baidu.com
    无效代理IP: HTTP://14.115.107.232:808
    无效代理IP: HTTP://14.115.107.232:808
    无法访问网页http://www.baidu.com
    无效代理IP: HTTPS://113.78.255.93:9000
    无效代理IP: HTTPS://113.78.255.93:9000
    无法访问网页http://www.baidu.com
    无效代理IP: HTTPS://60.191.11.237:3128
    无效代理IP: HTTPS://60.191.11.237:3128
    无法访问网页http://www.baidu.com
    无效代理IP: HTTPS://58.255.38.156:9000
    无效代理IP: HTTPS://58.255.38.156:9000
    无法访问网页http://www.baidu.com
    无效代理IP: HTTP://163.125.71.195:8888
    无效代理IP: HTTP://163.125.71.195:8888
    无法访问网页http://www.baidu.com
    无效代理IP: HTTP://123.163.24.113:3128
    无效代理IP: HTTP://123.163.24.113:3128
    无法访问网页http://www.baidu.com
    无效代理IP: HTTP://222.240.184.126:8086
    无效代理IP: HTTP://222.240.184.126:8086
    无法访问网页http://www.baidu.com
    无效代理IP: HTTPS://117.141.155.241:53281
    无效代理IP: HTTPS://117.141.155.241:53281
    无法访问网页http://www.baidu.com
    无效代理IP: HTTPS://218.22.7.62:53281
    无效代理IP: HTTPS://218.22.7.62:53281
    无法访问网页http://www.baidu.com
    无效代理IP: HTTPS://121.13.252.60:41564
    无效代理IP: HTTPS://121.13.252.60:41564
    无法访问网页http://www.baidu.com
    无效代理IP: HTTPS://125.123.139.19:9000
    无效代理IP: HTTPS://125.123.139.19:9000
    无法访问网页http://www.baidu.com
    无效代理IP: HTTPS://117.88.177.101:3000
    无效代理IP: HTTPS://117.88.177.101:3000
    无法访问网页http://www.baidu.com
    无效代理IP: HTTPS://116.204.142.62:8080
    无效代理IP: HTTPS://116.204.142.62:8080
    无法访问网页http://www.baidu.com
    无效代理IP: HTTPS://114.99.54.65:8118
    无效代理IP: HTTPS://114.99.54.65:8118
    无法访问网页http://www.baidu.com
    无效代理IP: HTTPS://60.191.11.229:3128
    无效代理IP: HTTPS://60.191.11.229:3128
    无法访问网页http://www.baidu.com
    无效代理IP: HTTPS://119.4.13.26:1133
    无效代理IP: HTTPS://119.4.13.26:1133
    无法访问网页http://www.baidu.com
    无效代理IP: HTTPS://113.78.255.93:9000
    无效代理IP: HTTPS://113.78.255.93:9000
    无法访问网页http://www.baidu.com
    无效代理IP: HTTPS://117.45.139.84:9006
    无效代理IP: HTTPS://117.45.139.84:9006
    无法访问网页http://www.baidu.com
    无效代理IP: HTTPS://60.191.11.237:3128
    无效代理IP: HTTPS://60.191.11.237:3128
    无法访问网页http://www.baidu.com
    无效代理IP: HTTPS://171.35.86.72:8118
    无效代理IP: HTTPS://171.35.86.72:8118
    无法访问网页http://www.baidu.com
    无效代理IP: HTTPS://58.255.38.156:9000
    无效代理IP: HTTPS://58.255.38.156:9000
    无法访问网页http://www.baidu.com
    无效代理IP: HTTPS://114.223.103.47:8118
    无效代理IP: HTTPS://114.223.103.47:8118
    无法访问网页http://www.baidu.com
    无效代理IP: HTTPS://117.141.155.241:53281
    无效代理IP: HTTPS://117.141.155.241:53281
    无法访问网页http://www.baidu.com
    无效代理IP: HTTPS://218.22.7.62:53281
    无效代理IP: HTTPS://218.22.7.62:53281
    无法访问网页http://www.baidu.com
    无效代理IP: HTTPS://14.153.52.10:3128
    无效代理IP: HTTPS://14.153.52.10:3128
    无法访问网页http://www.baidu.com
    无效代理IP: HTTPS://61.164.39.69:53281
    无效代理IP: HTTPS://61.164.39.69:53281
    有效代理IP: HTTPS://113.65.163.199:9797
    源IP地址为:14.145.235.76
    ========================================
    无法访问网页http://www.baidu.com
    无效代理IP: HTTPS://58.251.235.76:9797
    无效代理IP: HTTPS://58.251.235.76:9797
    无法访问网页http://www.baidu.com
    无效代理IP: HTTPS://183.166.103.164:9999
    无效代理IP: HTTPS://183.166.103.164:9999
    无法访问网页http://www.baidu.com
    无效代理IP: HTTP://112.95.205.138:8888
    无效代理IP: HTTP://112.95.205.138:8888
    无法访问网页http://www.baidu.com
    无效代理IP: HTTP://14.115.105.104:808
    无效代理IP: HTTP://14.115.105.104:808
    无法访问网页http://www.baidu.com
    无效代理IP: HTTP://113.194.28.11:9999
    无效代理IP: HTTP://113.194.28.11:9999
    无法访问网页http://www.baidu.com
    无效代理IP: HTTP://60.191.11.249:3128
    无效代理IP: HTTP://60.191.11.249:3128
    

    关于http和https代理

    • 可以看到proxies中有两个键值对:
    • {‘http’: ‘http://IP:port‘,‘https’:'https://IP:port‘}
    • 其中 HTTP 代理,只代理 HTTP 网站,对于 HTTPS 的网站不起作用,也就是说,用的是本机 IP,反之亦然。
    • 我刚才使用的验证的网站是https://jsonip.com, 是HTTPS网站所以探测到的有效代理中,如果是https代理,则返回的是代理地址
    • 如果是http代理,将使用本机IP进行访问,返回的是我的公网IP地址
    
    
    展开全文
  • 国内免费高匿IP代理软件

    万次阅读 2021-08-20 09:50:06
    免费IP代理软件能快速获取代理ip资源,智能验证,一键设置取消代理。 免费IP代理软件 1.支持免费IP代理 2.普通代理 3.高匿代理 4.Http代理 5.Https代理 6.自动验证无效代理 7.一键设置取消代理 8.导出到文本或...
  • Java实现Ip代理

    千次阅读 2019-01-19 14:49:20
    设置Ip代理很多时候都会有用到,尤其是在写爬虫相关项目的时候。虽然自己目前没有接触这种需求,但由于最近比较闲,就写着当作练习吧 爬取代理IP 爬取 关于爬取代理IP,国内首先想到的网站当然是 西刺代理 。首先写...
  • 百度搜索:爬虫IP池, 就有很多网站,这些网站一般都有提供免费的代理IP。但是这些IP质量不高,需要自己手动复制粘贴,测试后再使用,效率底下。我们可以写个爬虫,批量获取免费IP,自动测试后,再使用。 本篇文章...
  • 免费IP代理

    千次阅读 2021-01-21 15:39:44
    20、http://www.nimadaili.com/泥马IP代理 19、http://lab.crossincode.com/proxy/Crossin编程教室 18、http://www.xsdaili.com/dayProxy/ip/1415.html小舒代理 17、http://www.xiladaili.com/西拉免费代理IP 16...
  • 有哪些国内免费ip代理工具?

    千次阅读 2021-08-09 17:15:37
    在日常生活中,很多人因为工作需要使用代理IP上网,很多人因为其他原因使用代理IP上网,但也有一些人不知道如何更换ip。我们来看看有什么方法。 1、更改电脑ip地址 右键单击计算机的网络图标并选择属性。您还可以...
  • Python爬虫实战——搭建自己的IP代理

    万次阅读 多人点赞 2018-10-30 15:49:20
    如今爬虫越来越多,一些网站网站加强反爬措施,其中最为常见的就是限制IP,对于爬虫爱好者来说,能有一个属于自己的IP代理池,在爬虫的道路上会减少很多麻烦 环境参数 工具 详情 服务器 Ubuntu 编辑器...
  • 永久免费的ip代理怎么获取?

    千次阅读 2021-08-04 09:36:54
    一般IP代理需要服务器架设才能使用,架设好后才能使用。一般而言,不存在免费,因为租用服务器是要花钱的,再就是安装IP代理需要技术,因此,市场上一般都是很少有免费的,但也不排除,一些好人,愿意来做免费的,让...
  • IP代理proxy试用

    千次阅读 2019-04-30 09:09:27
    IP代理试用
  • 代理池就是用于应付网站的反爬虫的备用代理ip集合。 做过爬虫都知道,在抓取某些网站的时候,如果你抓取的频率太高了,你的ip就会被该网站封掉或者说屏蔽掉,接下来你就会爬取失败,所以此时你就需要使用代理来解决...
  • python-requests模块实现ip代理

    千次阅读 2020-09-28 20:41:15
    import json import telnetlib import requests import random ...# 写入可用ip代理池文件路径 ip_pool_file = "verified_proxies.json" # 用于测试代理ip是否可用的网站 test_url = "http://icanhazip.com
  • 国内IP代理哪个比较好一些稳定线路多呢,想必很多朋友都在寻找一款合适自己的IP代理软件。截图给大家推荐的这款软件,用过的肯定不会陌生,那就是领导者IP代理,老牌子了,值得信赖,无论稳定性,还是速度始终如一,...
  • IP代理

    万次阅读 2018-08-02 12:08:46
    该项目旨在提供批量免费的代理IP地址,思路参考自作者崔庆才的书籍《Python3 网络爬虫开发实战》第九章–代理的使用–代理池的维护,在此感谢作者的无私贡献!项目的分模块思想借鉴了作者的思路,但代码实现不同。 ...
  • 腾讯云搭建Socks5多IP代理服务器实现游戏单窗口单IP腾讯云多IP Socks5搭建教程 配合代理工具实现 单窗口单IP1.多IP服务器选择2.服务器购买功能快捷键合理的创建标题,有助于目录的生成如何改变文本的样式插入链接与...
  • 怎样简单的搭建一个免费的IP代理

    千次阅读 2018-09-15 10:52:38
    之前写过一篇python实战项目二:获取IP代理的文章,不过说实话,这个程序有几点不足,以至于不能愉快玩耍之后,我就重新整理了思路,又写了一个关于获取免费IP代理的代码。在这儿我想写反思一下之前这个代码的主要...
  • python构建IP代理池(Proxy Pool)

    千次阅读 2018-11-11 21:24:29
    如果设置了代理服务器 , 实际上就是在本机和服务器之间搭建了一个桥, 此时本机不是直接 向 Web 服务器发起请求,而是向代理服务器发出请求,请求会发送给代理服务器,然后由代理服务器再发...
  • 一、手动更新IP池 1.在settings配置文件中新增IP池: IPPOOL=[ {"ipaddr":"61.129.70.131:8080"}, {"ipaddr":"61.152.81.193:9100"}, {"ipaddr":"120....
  • 如何自己搭建ip代理服务器?

    千次阅读 2021-03-12 14:27:20
    在这篇文章之前,很多人应该看过很多代理ip池的文章,发现是漏洞,不能使用。比较多的1.建议购买x代理ip,2.抓住xx免费代理ip,自己写检查,写api,为爬虫提供使用。 第一种方法,不得不说,真的有几个好的代理ip。 ...
  • 住宅IP是ISP(互联网服务提供商)或者ADSL提供商分配给个人用户的实际家庭住宅IP地址,由100%的WIFI网络真实用户组成,家庭住宅IP是真实的用户设备IP,与普通网络用户使用的IP完全一致。 家庭住宅IP有什么特点? ...
  • 国外ip代理有哪些软件?

    千次阅读 2021-04-01 15:05:41
    今日要介绍的外国代理ip,做得比较好的是欧美国家和俄罗斯,以下十个品牌在著名的blackhatworld代理市场中名列前茅,当然,其中也有几个还没有中文客户服务,语言沟通有障碍的网友最好慎选。 一、Stormproxies 在...
  • 618IP代理,带你深入了解什么是IP地址,如何运用好IP地址,已经怎么更改自己的IP地址QQ3218080091 IP地址对于经常上网的人应该都不陌生,ip地址又可以分成内网ip地址和公网ip地址,今天就来简单介绍下这两者的区别。...
  • 感觉自己写得很复杂 还是自己太low了 ...建立用户代理池 #1.1建立一个 用户池 agents=[ "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36
  • 文章目录代理(Proxy)获取代理IP网站分析获取页面页面分析筛选代理IP 代理(Proxy) 代理(Proxy)是一种特殊的网络...在爬虫中可以使用IP代理来隐藏自己的真实IP地址,以达到反爬或者其他的目的。 获取代理IP 网...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 390,892
精华内容 156,356
关键字:

ip代理