分币不花,K哥带你白嫖海外代理 ip!

00

前言

近来,国内的数据采集环境越来越严峻,不是“非法入侵计算机信息系统”,就是“侵犯公民个人隐私信息”,一个帽子砸下来,直接就“包吃包住”,推荐阅读一下 【K哥爬虫普法专栏】。虽然大伙常说“搏一搏单车变摩托”,但这就像高空走钢丝,谁也说不好下一步会不会掉入万丈深渊。因此何不换个赛道,把目标放到各类海外数据,比如海外电商平台、社交媒体平台等等,同样能带来巨大的价值,最重要的,大多数人的技术也不足以惊动 FBI、ICPO,整个国际红色通缉令,被跨国追捕 ≖‿≖。

不过很多海外平台都有着较严格的风控策略,既然咱无法“肉身出国”,全球各地到处跑,最好的选择自然是使用海外代理 ip,但是大多数海外代理 ip 都价格不菲,下图是一家海外代理商官网的 ISP(住宅)按流量付费产品的价格表,注意货币单位可是“美元”:

01

这么一来,采集海外数据的成本就太高了,那有什么好的解决办法呢?自然是有的,K哥深知大伙都坚决贯彻着“能白嫖绝不付费”的思想,有免费的用绝不花钱买 ( ´◔ ‸◔`),但是用过国内那些网站的免费代理的都知道,免费的真没啥好东西,质量堪忧。那么问题就来了,海外代理 ip 还更值钱一些,哪里能找到能用且好用的免费海外代理 ip 呢?K哥还真找到一个,本文将手把手教你如何采集该网站的免费海外代理 ip,并给出源代码,一起来给这年轻的网站“上上课”。

采集目标

  • 网站:https://www.iphaiwai.com/free

采集过程

该网站为快代理的海外独立站,首先进入到网页,可以看到有很多地区的海外代理 ip,美国、新加坡、泰国等等,全球各地的都有,而且都是高匿名的。这些 ip 时效都显示的 1-10 分钟,但是根据实际测试,部分 ip 半小时之后仍然可用。并且半小时刷新一次,也就是每隔半小时能获取到 12 个新的可用 ip,结合一些合理的调度策略,每天都能够不间断地“白嫖”~

当然,没必要整啥并发之类的,每半小时获取一次就可以了,不间断请求也不会给你一批新货,还会被封哦:

02

现在,咱们分析下如何采集这些海外代理 ip。

鼠标移动到网页上,右键查看页面源代码(ctrl+u),搜索一下目标 ip,会发现能直接搜索到,且其他 ip 相关数据也都在其中。证明这些数据不是通过接口传输的,可以直接使用一些常用的 Python 解析库,例如 XPath、pyquery 或者正则表达式等方法匹配到想要的数据,而且该页面大概率也是没啥反爬的:

03

那么,还是老样子,F12,先打开开发者人员工具进行抓包,刷新网页,可以看到,https://www.iphaiwai.com/free/ 请求的响应内容包含我们所需要的 html 源代码:

04

先点击开发者人员工具左上角的按钮,检查网页元素,再随便点击一个 ip,即可跳转到其在 html 代码中的位置,页面是个表格样式,这里自然就是一些 tr、td 标签,tr 包裹了每行的内容,td 则对应该行中每个单元格的值,如下图所示:

05

这里我们使用 lxml 解析库中的 Xpath 方法来匹配这部分内容,先简单介绍一下,XPath(XML Path Language)是一种用于在 XML 文档中查找信息的语言,通过特定的路径表达式来匹配在 XML 文档结构中的位置。使用前,需要先安装一下 lxml 解析库:

# 直接安装
pip install lxml
# 镜像安装
pip install lxml -i https://pypi.tuna.tsinghua.edu.cn/simple

下面是 Xpath 的一些基本表达式,更详细的可以阅读 K 哥往期文章 【0基础学爬虫】爬虫基础之网页解析库的使用:

06

我们需要获取 <td data-title="IP">134.35.9.162</td> 中的 ip 值,只用匹配 td 标签的属性 data-title 值为 IP 的即可,基本写法如下:

import requests
from lxml import etree
from loguru import logger


headers = {
    "user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36 Edg/120.0.0.0"
}
url = "https://www.iphaiwai.com/free/"
response = requests.get(url, headers=headers, timeout=5)

# 获取 ip
# xpath 匹配 ip 值
html = etree.HTML(response.text)
ip_list = html.xpath("//td[@data-title='IP']/text()")
logger.info(ip_list)

如果还想要别的数据,例如时效、位置等等,方法也都一样,依此类推。这里的样式较为简单,比较容易就能够匹配到值,一般复杂些的,我们可以用些工具先校验一下 xpath 表达式是否正确,比如浏览器插件 XPath Helper,能够显示出输入的 xpath 表达式匹配出来的结果。该插件可以去K哥公众号回复关键字 XPath Helper 获取。

插件安装后,按快捷键 ctrl + shift + x 即可启动。以下为结果验证,可以看到,该表达式正确匹配到了 12 个 ip 值:

07

完整代码

以下代码只是简单实现了一些基本的功能,可以根据自己的需求进行相应的调整,经过K哥测试,这些 ip 好像不区分使用环境,大家可以自行测试一下:

# ======================
# -*-coding: Utf-8 -*-
# author: K哥爬虫
# ======================
import requests
from lxml import etree
from loguru import logger
from concurrent.futures import ThreadPoolExecutor, as_completed

# 免费海外代理 ip 页
FREE_IP_URL = 'https://www.iphaiwai.com/free'
# 验证网站
VERIFY_URL = 'https://web.whatsapp.com'


class OverseasFree:
    def __init__(self):
        self.headers = {
            "Accept-Encoding": "gzip",
            "user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36 Edg/120.0.0.0"
        }
        self.effective_ip_list = []

    @staticmethod
    def get_proxies(proxy: str) -> dict:
        proxies = {
            "http": "http://%(proxy)s/" % {"proxy": proxy},
            "https": "http://%(proxy)s/" % {"proxy": proxy}
        }
        return proxies

    def verify_ip(self, proxy_ip_data: str):
        """
        验证 ip 可用性
        :param proxy_ip_data: 获取到的免费海外代理 ip
        """
        # 获取代理 ip
        proxy = proxy_ip_data.split(',')[0]
        proxies = self.get_proxies(proxy)
        try:
            # 验证可用性, 国内环境无法访问该网站
            response = requests.get(url=VERIFY_URL, proxies=proxies, timeout=20)
            response.encoding = 'utf-8'
            # <title>WhatsApp Web</title>
            if response.status_code == 200:
                logger.success('ip <%s> verify success' % proxy)
                self.effective_ip_list.append(proxy_ip_data)
            else:
                logger.error('ip <%s> verify error, status code: %s' % (proxy, response.status_code))
        except Exception as e:
            logger.error('ip <%s> verify error: %s' % (proxy, e))

    def get_data(self) -> list:
        """
        获取 ip 相关信息
        """
        try:
            response = requests.get(url=FREE_IP_URL, headers=self.headers, timeout=5)
            html = etree.HTML(response.text)

            # 获取 ip
            ip_list = html.xpath("//td[@data-title='IP']/text()")
            port_list = html.xpath("//td[@data-title='PORT']/text()")

            # 获取 ip 位置
            area_list = html.xpath("//td[@data-title='位置']/text()")

            # 获取 ip 有效期
            period_of_validity_list = html.xpath("//td[@data-title='IP时效(分钟)']/text()")

            # 获取到的所有 ip 的相关数据
            proxy_list = [f"{ip}:{port}, {area}, {period}" for ip, port, area, period in zip(ip_list, port_list, area_list, period_of_validity_list)]

            return proxy_list
        except Exception as e:
            logger.error('get ip error: %s' % e)

    def main(self):
        # 获取所有的免费代理 ip
        proxy_data_list = self.get_data()

        # 验证 ip 可用性
        with ThreadPoolExecutor(max_workers=12) as executor:
            futures = [executor.submit(self.verify_ip, proxy) for proxy in proxy_data_list]
        verify_result = [future.result() for future in as_completed(futures)]
        if verify_result:
            # 处理返回的数据
            pass

        # 打印所有的有效 ip
        logger.info(self.effective_ip_list)
        logger.info('Get IP Number: %d' % len(self.effective_ip_list))


if __name__ == '__main__':
    OverseasFree().main()

结果验证

08

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/350135.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

weak_ptr 与 一个难发现的错误(循环依赖问题)笔记

推荐B站视频&#xff1a;7.weak_ptr与一个非常难发现的错误_哔哩哔哩_bilibilihttps://www.bilibili.com/video/BV18B4y187uL/?p7&spm_id_frompageDriver&vd_sourcea934d7fc6f47698a29dac90a922ba5a3一、weak_ptr weak_ptr并不拥有所有权并不能调用 -> 和 解引…

【MySQL】如何使用图形化界面DataGrip操作数据库

&#x1f308;个人主页: Aileen_0v0 &#x1f525;热门专栏: 华为鸿蒙系统学习|计算机网络|数据结构与算法 ​&#x1f4ab;个人格言:“没有罗马,那就自己创造罗马~” #mermaid-svg-W5JDg0WA1tjEP66Y {font-family:"trebuchet ms",verdana,arial,sans-serif;font-siz…

uniapp Android 离线打包之未配置appkey或配置错误

1、去官网申请appKey: 申请Appkey 2、项目中使用appKey: <meta-dataandroid:name"dcloud_appkey"android:value"794534204bbae06989........" />3、参考 官方教程&#xff0c;修改配置&#xff1a; 配置教程 注意&#xff1a; 本地的appId 和 官…

如何解决Flutter应用程序的兼容性问题

随着移动应用开发领域的不断发展&#xff0c;Flutter作为一种跨平台框架&#xff0c;受到了越来越多开发者的青睐。要确保Flutter应用程序能够在不同的设备和操作系统上稳定运行&#xff0c;并提供一致的用户体验&#xff0c;我们需要重视应用程序的兼容性问题。下面将简单的介…

【代码随想录-数组】有序数组的平方

💝💝💝欢迎来到我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学习,不断总结,共同进步,活到老学到老导航 檀越剑指大厂系列:全面总结 jav…

HTML-表单

表单 概念&#xff1a;一个包含交互的区域&#xff0c;用于收集用户提供的数据。 1.基本结构 示例代码&#xff1a; <form action"https://www.baidu.com/s" target"_blank" method"get"><input type"text" name"wd&q…

独立站怎么建设对seo好?

现如今市面上就有不少开源的建站程序可供挑选&#xff0c;哪怕你不懂技术&#xff0c;不懂代码&#xff0c;也能建自己的独立站&#xff0c;效果比不少所谓的用自己技术开发的站都要好&#xff0c;本身做一个网站不难&#xff0c;但你做网站的目的是什么&#xff1f;是为了在搜…

ctf-idea调试jar包

0.拿到jar包并解压 进入解压出来的目录,然后以该目录打开项目 1.设置maven 设不设置都行 2.添加依赖 添加两个依赖, boot-inf下的 classes和lib 3.配置调试器 添加 remote jvm debug 1.根据jdk版本选择调试参数 2.选择module classpath为解压后的文件夹名 如图,运行jar包的…

代码随想录Day31 | 贪心算法 455.分发饼干 376. 摆动序列 53. 最大子序和

代码随想录Day31 | 贪心算法 455.分发饼干 376. 摆动序列 53. 最大子序和 贪心算法455.分发饼干376.摆动序列53.最大子序和 贪心算法 局部最佳 --> 全局最佳 刷题或者面试的时候&#xff0c;手动模拟一下感觉可以局部最优推出整体最优&#xff0c;而且想不到反例&#xff0…

【QT+QGIS跨平台编译】之九:【LZ4+Qt跨平台编译】(一套代码、一套框架,跨平台编译)

文章目录 一、LZ4介绍二、文件下载三、文件分析四、pro文件五、编译实践一、LZ4介绍 LZ4是一种无损压缩算法,压缩速度为每核心400MB/s。 LZ4是目前效率最高的压缩算法,更加侧重于压缩/解压缩速度,压缩比并不突出,本质上就是时间换空间。 LZ4库是使用BSD许可证作为开放源码…

Linux——shell程序的简单实现

shell程序的简单实现 本章思维导图&#xff1a; 注&#xff1a;本章思维导图对应的.xmind和.png文件都已同步导入至资源&#xff0c;可免费查阅 在学习完有关进程的知识后&#xff0c;我们就可以开始尝试自己实现一个简单的shell程序了。 注&#xff1a;在编写简单的shell程…

Linux实现:从倒计时到进度条

文章目录 1.回车与换行2.缓冲区的概念3.倒计时4.进度条(第一版无应用场景)5.进度条(第二版有应用场景) 1.回车与换行 2.缓冲区的概念 强制刷新可以使用冲刷函数fflush #include <stdio.h> #include <unistd.h> int main() {printf("I am a \nhandsome man!&q…

leetcode 第三弹

链表声明&#xff1a; * Definition for singly-linked list.* struct ListNode {* int val;* ListNode *next;* ListNode() : val(0), next(nullptr) {}* ListNode(int x) : val(x), next(nullptr) {}* ListNode(int x, ListNode *next) : val(x), next(n…

【K12】tk窗口+plt图像功能-学习物理中的串并联研究【附源码说明】

程序源码 import tkinter as tk import matplotlib.pyplot as plt# 初始化 matplotlib 的字体设置 plt.rcParams[font.family] SimHei# 计算串联电路的函数 def calculate_series():try:# 获取用户输入的电阻值并转换为浮点数r1 float(entry_r1.get())r2 float(entry_r2.ge…

【CANoe使用大全】——Trace窗口

&#x1f64b;‍♂️【CANoe使用大全】系列&#x1f481;‍♂️点击跳转 文章目录 1.Trace作用2.Trace窗口打开方式2.1.Analysis—>Trace2.2.Measurement Setup ------> Trace 3.Trace窗口菜单栏介绍3.1. Detail View3.1. Statistic View3.3.Difference view3.4.Predefi…

【开发问题问题解决开发小技巧】通用资源管理01

【问题】新增应该输出提示但是出现乱码 查看会话发现是会话已结束&#xff0c;好家伙 重新登录会话依旧新增失败&#xff0c; 原来是提交的项没添加ORZ 【问题】会话保护 将会话保护改为“无限制” 执行修改提交但是一直在加载中&#xff0c;回滚后执行直接跳出来“未找到驱动程…

js打地鼠

文章目录 1实现效果2代码实现 1实现效果 游戏难度&#xff1a;简单&#xff0c;一般&#xff0c;困难&#xff0c;噩梦&#xff08;控制setInterval的time参数&#xff09; 按钮功能&#xff1a;结束&#xff08;可以通过修改gameScore的值来修改判定结束的分数&#xff09;&am…

MySQL十部曲之四:MySQL中的数据类型

文章目录 前言概述数字类型数字类型语法数字类型字面量十六进制字面量位字面量布尔字面量 数字类型的属性超出范围和溢出处理 时间和日期类型时间和日期类型语法DATE、DATETIME和TIMESTAMP的异同TIMESTAMP和DATETIME的自动初始化和更新时间和日期字面量 字符串类型字符串类型语…

知识圣殿,智慧熔炉

知识圣殿&#xff0c;智慧熔炉 知识殿堂&#xff0c;巍然屹立 一座灵魂熔炉&#xff0c;号称图书馆 万卷书香盈架&#xff0c;智慧如星河汇聚 每一册书页&#xff0c;流淌着人类文明的血脉 钢笔与墨水交织诗篇 思想发芽&#xff0c;真理绽放光焰 浩瀚知识海洋&#xff0c;波涛…

tensorboard+seaborn 画RL论文图片

概要 tensorboard记录数据&#xff0c;并保存为fie_name.csv 文件加载file_name.csv文件, 处理加载得到数据,然后通过seaborn 显示出来。 1. tensorboard 通常来说&#xff0c;我们一般会用 tensorboard 去记录一些数据。 所以我们先介绍一下 tensorboard 一些注意事项 seti…