V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
tikazyq
V2EX  ›  Python

为爬虫构建代理池

  •  
  •   tikazyq ·
    tikazyq · 2016-07-15 18:10:31 +08:00 · 13747 次点击
    这是一个创建于 3051 天前的主题,其中的信息可能已经有所发展或是发生改变。

    为了避免爬虫被封 IP ,网上搜索教程说需要建立代理池。但是付费代理都好贵。。。不过好在网上已经有不少免费提供代理的网站了。因此,我打算写个爬虫去获取这些免费 IP ~

    策略

    • 步骤 1. 用种子关键词例如“代理 IP ”在各个搜索引擎上搜索,获取候选 URL
    • 步骤 2. 爬取候选 URL ,将代理地址储存下来
    • 步骤 3. 验证代理地址,将可用的代理地址放入代理池

    难点

    1. 如何去验证维护这些代理地址
    2. 如何知道哪些代理地址适合哪些网站(可用性,响应时间)
    3. 效率问题(之前写过简单的验证脚本,但是效率非常低)

    小伙伴们有不有什么好的办法能解决这些问题呢?

    49 条回复    2017-10-10 17:22:52 +08:00
    facat
        1
    facat  
       2016-07-15 18:13:44 +08:00 via Android
    用代理池中的代理访问百度,记录获取页面的时间。
    tikazyq
        2
    tikazyq  
    OP
       2016-07-15 18:22:53 +08:00
    @facat 多谢 这个可行的 不过怎么解决效率问题呢?而且有些代理直接指向单一网站,这种如何检测啊
    hansnow
        3
    hansnow  
       2016-07-15 18:26:52 +08:00
    @facat 如果这么做的话会不会因为代理那边的缓存而导致结果不准确呢
    jnduan
        4
    jnduan  
       2016-07-15 18:28:41 +08:00
    付费代理包月也就 300 左右,跟抓来的数据相比,太便宜了
    hansnow
        5
    hansnow  
       2016-07-15 18:31:09 +08:00
    @jnduan 请问有推荐咩?
    ji4ozhu
        6
    ji4ozhu  
       2016-07-15 18:33:58 +08:00
    binux
        7
    binux  
       2016-07-15 18:35:29 +08:00   ❤️ 1
    自己的验证地址,异步 IO ,短超时。
    一般如果能访问地自己的验证地址,大部分网站都没有问题。除非你有量特别大的特殊网站,比如淘宝,可以单独测。
    josephshen
        8
    josephshen  
       2016-07-15 19:08:19 +08:00 via iPhone
    我原来也和你一样这样想,后来发现花钱买代理提供商的更加方便,价格也很便宜。具体就不推荐了。
    tikazyq
        9
    tikazyq  
    OP
       2016-07-15 19:08:24 +08:00
    @binux 自己的验证地址是指提供代理的网站吗?
    tikazyq
        10
    tikazyq  
    OP
       2016-07-15 19:10:01 +08:00
    @josephshen 能推荐几个代理提供商嘛~
    binux
        11
    binux  
       2016-07-15 19:21:38 +08:00
    @tikazyq 指验证代理时访问的网站
    josephshen
        12
    josephshen  
       2016-07-15 19:32:05 +08:00 via iPhone
    你可以搜一下先,在这个过程中你会自己有比较,会学到其它东西的,公网上不应该随便告诉一个人应该怎样做
    ELIOTT
        13
    ELIOTT  
       2016-07-15 19:54:15 +08:00
    記得 Hola 有個產品是專門賣代理池的.
    UnisandK
        15
    UnisandK  
       2016-07-15 20:51:45 +08:00
    http://ningning.today/2016/03/07/python/python-requests-tor-crawler/
    spikeLIN
        16
    spikeLIN  
       2016-07-15 21:17:21 +08:00 via iPhone
    我们代理池自己爬的⋯⋯
    greatghoul
        17
    greatghoul  
       2016-07-15 21:21:39 +08:00 via iPhone
    我用的快代理,挺不错的
    Soar360
        18
    Soar360  
       2016-07-15 21:46:14 +08:00
    这东西,折腾起来很简单,我折腾过好几次了,能维持在 3000 左右的可用 IP 。
    demonchang
        19
    demonchang  
       2016-07-15 22:35:55 +08:00 via iPhone
    。。。刚好要搞这个。爬的太麻烦。买的能好点吧。但是不知道买那个。求推荐
    techmoe
        20
    techmoe  
       2016-07-15 22:55:20 +08:00 via Android
    tor
    techmoe
        21
    techmoe  
       2016-07-15 22:57:54 +08:00 via Android
    tor 这个东西有时候感觉真的挺好的 虽然有点杀鸡总宰牛刀的感觉
    py 端想控制 tor 可以用 stem 这个库
    遗憾的是我暂时没找到在同一环境下开两个 tor tunnel 的办法,拿 stem 的 process 相关方法开启一个再开第二个死活打不开,不知道为什么
    Arnie97
        22
    Arnie97  
       2016-07-15 23:14:36 +08:00 via Android
    如果只是需要不同 IP ,可以通过 PPPoE 重新拨号换 IP
    alexapollo
        23
    alexapollo  
       2016-07-15 23:22:11 +08:00
    做的时候你会发现很多问题的, LOL
    loalj
        24
    loalj  
       2016-07-15 23:43:20 +08:00   ❤️ 1
    我最近也在研究这个代理池的问题,写了一个动态管理代理池的程序。 schedule 每隔一段时间去验证代理池中各个 ip 响应时间,计算权重,存到数据库里边。当有 request 进来的时候根据权重值去分配代理,将请求转发给代理。这就相当于在本地开启了一个代理,上游是代理池。

    ```
    requests.get(url, proixes={"http": "http://127.0.0.1:8399"})
    ```
    [github]( https://github.com/loadlj/rzproxy)
    代码还在完善中,欢迎一起改进 :)
    tikazyq
        25
    tikazyq  
    OP
       2016-07-16 00:48:41 +08:00
    @loalj 似乎可以作为验证代理的方案~明天空了测试一下
    tikazyq
        26
    tikazyq  
    OP
       2016-07-16 00:49:16 +08:00
    @spikeLIN 有不有什么方法可以借鉴一下嘛?~
    tikazyq
        27
    tikazyq  
    OP
       2016-07-16 00:52:08 +08:00
    @UnisandK 赞👍!感觉是个解决方案,稍微看了一下不是很懂,还需要研究一下~
    tikazyq
        28
    tikazyq  
    OP
       2016-07-16 01:02:21 +08:00
    @techmoe 有不有什么教程可以参考学习一下嘛?
    hard2reg
        29
    hard2reg  
       2016-07-16 04:09:55 +08:00
    这种事我做过。。。自动挑选出最优的 IP 。。。但是大多数都没卵用,真正能用的没多少,楼主还是放弃吧
    g079708
        30
    g079708  
       2016-07-16 05:19:43 +08:00 via iPhone
    进来学习一下。
    kslr
        31
    kslr  
       2016-07-16 05:28:26 +08:00
    @loalj

    性能如何呢?我在考虑用 go 写一套扫描和检查
    RqPS6rhmP3Nyn3Tm
        32
    RqPS6rhmP3Nyn3Tm  
       2016-07-16 05:50:52 +08:00 via Android
    如果对速度没啥要求, Tor 真的挺不错的
    techmoe
        33
    techmoe  
       2016-07-16 08:35:19 +08:00 via Android
    h4x3rotab
        34
    h4x3rotab  
       2016-07-16 09:08:54 +08:00 via iPhone
    用 tor 爬数据对其他用户非常不负责任,如果我发现了这种 ip 池,我会想办法把里面的 ip 找出来然后公布代理黑名单,允许各网站把这些 ip 全 ban 掉
    facat
        35
    facat  
       2016-07-16 09:55:50 +08:00 via Android
    @tikazyq
    @hansnow
    用多线程可以把带宽用慢。遇到缓存之类的也没办法,这个方法不能保证检查的代理 100%可用。
    kohnv
        36
    kohnv  
       2016-07-16 10:14:35 +08:00
    https://github.com/kohn/HttpProxyMiddleware
    针对网上的免费代理做的代理池, 解决了 lz 难点中的第一点.
    kohnv
        37
    kohnv  
       2016-07-16 10:16:12 +08:00
    不好意思 说到爬虫想当然以为是 scrapy 了.
    kohnv
        38
    kohnv  
       2016-07-16 10:30:42 +08:00
    说说当时遇到的一些问题和解决方案吧.

    1. 验证代理可不可用可以用这个代理去抓取某个很短的网页, 例如我当时是从百度主页随便找了一个 ajax 请求的 URL, 然后比较爬到的内容是不是正常. 这样可以剔除掉不可用的代理, 并把可用的加到代理池中. 这里所谓的不可用其实有多种可能, 例如超时, 返回 501 等异常状态码, 返回广告页面等. 光测试 ip 响应时间是不行的, 只能检查到超时的情况. 这样做确实验证的速度很慢, 但是实际运行过程中好几小时才需要抓取新代理, 然后验证, 因此对吞吐量的影响并不大. 这里的前提是只在加入到代理池时验证一次, 在使用过程中不再定期验证, 否则的话会极大的影响效率.

    2. 网上的免费代理有效时间不长, 例如刚刚验证过能用的代理, 可能过了十几分钟不能用了. 所以哪怕是经过了验证的代理也仍然是不能完全信任的, 代理池中需要在发现代理不能用的时候剔除不可用的代理. 如何发现代理不能用其实是个问题, 对于超时, 501 等状态码可以再代理池中检查, 但是有些代理返回广告页面, 那么代理池在不知道用户想爬什么内容的情况是无法分辨取到的 response 是正常的还是代理返回的广告. 因此这里需要有爬虫在 parse 过程中发现异常之后主动通知代理池代理不可用. 当然你也完全可以假设, 通过第一步中验证的代理哪怕不可用了也只是超时, 不会出现刚开始可用, 后来返回广告这种情况.

    3. 有些代理会缓存页面, 导致爬到的内容是旧的, 这个目前我也没想到办法. 不过好在我爬的页面不会频繁更新, 爬到过期的数据也无所谓.
    lynnworld
        39
    lynnworld  
       2016-07-16 12:08:20 +08:00
    有一种主机叫拨号主机, ip 被封重新拨号就好。网上搜,很多的
    qdk0901
        40
    qdk0901  
       2016-07-16 13:06:55 +08:00
    用 tor ,贴个我试验过的 nodejs 版,还不错。能应付一小时一个 ip 只能访问 60 次的限制
    http://transing.xyz/2016/05/12/using-tor-for-crawler/
    rapospectre
        41
    rapospectre  
       2016-07-16 13:26:06 +08:00
    恰好之前做过一样的工作,当时也是需要代理,然后自己写了爬虫做自动获取和自动更新。

    代理地址的话我没有去让爬虫自己选网站,而是人工筛选了几个提供免费代理的网站然后分别写了一些爬虫去爬不同的代理网站;

    针对你说的难点:

    1. 验证的话初次爬到的地址会直接先验证是否可用,能用再存入数据库或持久化;因为代理的不可靠性,需要定时检查抓到的代理是否可用,我是直接在 uWSGI 服务器起了一个定时任务,每半小时会检查一次,每一小时会抓一次新的代理,当然你也可以用 crontab 之类的定时任务做;
    2. 直接用抓到的代理访问需要访问的网站,如果需要针对不同网站提供不同代理可以验证后把相关验证信息一起储存;
    3. 效率问题好处理,网络验证操作都是 i/o 密集型任务,用协程、多线程、多进程都可以解决, python 的 gil 不影响多线程提高 i/o 密集型任务的效率

    https://github.com/bluedazzle/multithreading-spider 之前我用 多线程 + queue 做的一个简单的代理爬虫, src 的 demo 里是具体例子,使用了简单的生产者消费者模型,爬到代理地址的爬虫当做生产者,验证代理可用性的爬虫当做消费者,可以显示具体任务进度。
    dikensrover
        42
    dikensrover  
       2016-07-16 13:42:06 +08:00
    学习了
    hunk
        43
    hunk  
       2016-07-16 14:21:47 +08:00
    大量的还是购买省事,小量的可以抓取免费服务器,需要多测试可用性。

    PS :一直好奇这些代理是哪来的。曾想过写些工具软件,在其中加入代理服务的代理,出售代理服务器。
    kohnv
        44
    kohnv  
       2016-07-16 14:35:51 +08:00
    @hunk 购买的其实也是不可靠的代理, 只不过人家帮你做了一个 api 封装, 你可以直接使用 api 来获取而不用自己抓了. 这些代理很多都不能用.

    貌似网上的代理都是他们开了几台 vps 然后 24 小时全网连接代理常用的端口一个个试出来, 很多是网络中某个人开了代理给自己用的, 也因此可能很快这个代理就没用了.
    coolloves
        45
    coolloves  
       2016-07-16 16:13:50 +08:00 via Android
    我是这样做的,先找代理网站爬下代理,然后定义验证地址来验证是否有限,然后存取
    在正式用的时候,遇到无效的就记录无效次数加 1 ,成功的也记录次数加 1 ,然后一段时间内根据成功失败记录来清理代理池,留下定义多少概率的代理,
    loalj
        46
    loalj  
       2016-07-16 22:38:46 +08:00
    @kslr 我自己用的时候开过几十个并发,好像没多大问题。
    lbp0200
        47
    lbp0200  
       2016-07-16 23:51:06 +08:00
    长城宽带、方正宽带,自带动态 ip
    regeditms
        48
    regeditms  
       2016-08-07 10:55:47 +08:00
    @jnduan 请问。付费代理那里找呢、要可用性很高的。
    ji4ozhu
        49
    ji4ozhu  
       2017-10-10 17:22:52 +08:00
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   3631 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 29ms · UTC 05:07 · PVG 13:07 · LAX 21:07 · JFK 00:07
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.