更多>>关于我们

西安鲲之鹏网络信息技术有限公司从2010年开始专注于Web(网站)数据抓取领域。致力于为广大中国客户提供准确、快捷的数据采集相关服务。我们采用分布式系统架构,日采集网页数千万。我们拥有海量稳定高匿HTTP代理IP地址池,可以有效绕过各种反采集策略。

您只需告诉我们您想抓取的网站是什么,您感兴趣的字段有哪些,你需要的数据是哪种格式,我们将为您做所有的工作,最后把数据(或程序)交付给你。

数据的格式可以是CSV、JSON、XML、ACCESS、SQLITE、MSSQL、MYSQL等等。

更多>>官方微博

西安鲲之鹏
陕西 西安

加关注

  • Selenium disable Image loading in different browsers >>> http://tarunlalwani.com/post/selenium-disable-image-loading-different-browsers/ ​​​​
    发布时间:2018-07-11 18:21:10
  • chromedriver 镜像 - ChromeDriver Mirror >>> http://npm.taobao.org/mirrors/chromedriver/ ​​​​
    发布时间:2018-07-11 18:20:49
  • "全国POI信息数据库" 上线:涵盖美食、休闲娱乐、酒店、丽人等15大分类,覆盖全国350多个城市,数据量超过4700万条 >>> 点击前往:http://www.poilist.cn/ ​​​​
    发布时间:2018-07-11 15:28:47
  • 【最新发布】国内知名本地生活信息平台4794万商户POI数据2018年06月份更新 >>> http://www.site-digger.com/html/articles/20180702/647.html ​​​​
    发布时间:2018-07-02 11:25:13
  • 【CSV转Excel(XLSX格式)脚本分享】
    背景:大多数情况下CSV转Excel可以使用Openoffice或者Excel实现,但是偶尔也会遇到一些BT的情况,比如转换后Excel打开显示文件异常的(如图2所示)。于是乎利用xlsxwriter这个库写了个小脚本,用法如下:
    python csv2xlsx.py path-of-csv-file  file-encoding(default is utf-8)
    运行效果如图1所示。csv2xlsx.py源码链接分享 >>>https://bitbucket.org/snippets/qi/Xerx67
    发布时间:2018-06-21 18:57:26
  • 全国各类POI(美食、休闲娱乐、丽人、酒店、生活服务等等)用户评论数据7.09亿条,更新至2018年6月15日。点击查看示例数据 >>> http://t.cn/Rrv3RpO ​​​​
    发布时间:2018-06-21 10:21:20
  • 【经验分享】如何让Squid Web隧道支持SSH协议?
    默认Web隧道下连接22端口是不被允许的,会返回403错误。
    编辑/etc/squid3/squid.conf,加入如下配置行
    acl SSL_ports port 22
    acl Safe_ports port 22
    然后重启Squid即可。 ​​​​
    发布时间:2018-05-16 11:41:42
  • 当当网有多少图书,你知道吗?>>> http://t.cn/R3h6hiH ​​​​
    发布时间:2018-05-08 13:53:19
  • 【经验分享】Ubuntu下如何识别无线网卡?
    以普联的TL-WDN6200为例,使用的是rtl8812au(https://github.com/else05/rtl8812au这个驱动):
    wget http://t.cn/RuR1DrP
    unzip master.zip
    cd rtl8812au-master
    make
    sudo install
    然后重启系统,运气好的话你就能看到Wifi图标和热点列表了,如下图所示(Ubuntu14.04下亲测)。
    发布时间:2018-05-03 19:10:52
  • 【经验分享】DeleGate跑了3天日志吃了18G硬盘,如何关掉日志呢?
    查文档(ftp://www.delegate.org/pub/DeleGate/Manual.htm#LOGDIR),找到了方法,加上参数LOGFILE=""即可,原文:
    You can stop logging by specifying null file name like LOGFILE="" or PROTOLOG="". ​​​​
    发布时间:2018-04-28 18:08:15
当前位置: 首页 > 技术文章 >
如何在程序中处理reCAPTCHA?
发布时间:2015-04-08 来源:未知 浏览:

本文不是讲如何破解谷歌的reCAPTCHA(实际上我们也办不到),而是介绍在程序中借助第三方(人工)打码平台顺利通过reCAPTCHA验证。
由于使用人工打码会产生费用,并且费用是和调用次数成正比的,所以本方法仅适用于reCAPTCHA出现频率比较低的场景,例如:
1)网站登录使用了reCAPTCHA。比如,有时Linkedin登录就会出现reCAPTCHA(如下图所示),验证当前客户端是否是“真人”。

2)网站对访问频率过快的客户端返回reCAPTCHA,通过验证后即可继续访问。比如Zocdoc.com这个网站。

下面进入正题。如何在程序中借助第三方(人工)打码平台通过reCAPTCHA验证?
因为reCAPTCHA表单是JS动态创建的,我们遇到的第一个难题就是如何获取到reCAPTCHA表单中的验证码图片的路径及各隐藏表单域的值。
1)一个办法就是使用类似webkit的浏览器模拟工具(例如,phantomjs)加载页面,这样就能直接获取到JS生成的HTML源码。但是实现起来比较复杂,还需要借助第三方的软件。
2)查看源码会发现如果页面禁用了JS,reCAPTCHA将使用iframe模式加载(如下示),此时验证码图片路径和各表单项都是直接可见的。

<noscript> <iframe src="https://www.google.com/recaptcha/api/noscript?k=******" height="300" width="500" frameborder="0"></iframe> <br><textarea name="recaptcha_challenge_field" rows="3" cols="40"></textarea> </noscript>

所以我们直接请求“https://www.google.com/recaptcha/api/noscript?k=******”即可获取到验证码的图片路径和其它隐藏表单域的值。
这个问题解决了。接下来我们要获取到验证码图片对应的明文。如何调用第三方打码平台进行图片验证码识别呢?
我们需要先下载验证码图片,再把图片的二进制数据上传给打码平台,然后等待平台人工打码返回明文。打码平台一般都提供了供各种常见语言调用的API,所以该过程也比较简单。
现在我们已经获取到验证码图片对应的明文,只要我们将其和其它隐藏表单域参数一起提交就能完成验证过程了。

闲话不多说,还是直接上代码比较实在(Python实现, 这是我们真实项目中用到的):

# coding: utf-8
# recaptcha.py

import sys
import os
os.chdir(os.path.dirname(os.path.realpath(sys.argv[0])))
import re
import StringIO
import deathbycaptcha
from urlparse import urljoin
from webscraping import common, xpath

DEATHBYCAPTCHA_USERNAME = '******'
DEATHBYCAPTCHA_PASSWORD = '******'

def read_captcha(image):
    """image - fileobj, the captcha to be recognized
    """
    client = deathbycaptcha.SocketClient(DEATHBYCAPTCHA_USERNAME, DEATHBYCAPTCHA_PASSWORD)
    try:
        balance = client.get_balance()
        # Put your CAPTCHA file name or file-like object, and optional
        # solving timeout (in seconds) here:
        common.logger.info('Submit captcha to http://deathbycaptcha.com/.')
        captcha = client.decode(image)
        if captcha:
            # The CAPTCHA was solved; captcha["captcha"] item holds its
            # numeric ID, and captcha["text"] item its text.
            common.logger.info("CAPTCHA %s solved: %s" % (captcha["captcha"], captcha["text"]))
            return captcha["text"].strip()
    except deathbycaptcha.AccessDeniedException:
        # Access to DBC API denied, check your credentials and/or balance
        common.logger.info('Access to DBC API denied, check your credentials and/or balance')

def solve_recaptcha(html, D):
    """To solve the Google recaptcha
    """
    m = re.compile(r']+src="(https?://www\.google\.com/recaptcha/api/noscript\?k=[^"]+)"', re.IGNORECASE).search(html)
    if m:
        common.logger.info('Need to solve the recaptcha.')
        # need to solve the captcha first
        iframe_url = m.groups()[0]
        # load google recaptcha page
        iframe_html = D.get(iframe_url, read_cache=False)
        # extract recaptcha_challenge_field value for future use
        recaptcha_challenge_field = xpath.get(iframe_html, '//input[@id="recaptcha_challenge_field"]/@value')
        if recaptcha_challenge_field:
            # extract captcha image link
            captcha_image_url = xpath.get(iframe_html, '//img/@src')
            if captcha_image_url:
                captcha_image_url = urljoin(iframe_url, captcha_image_url)
                # download captcha
                captcha_bytes = D.get(captcha_image_url, read_cache=False)
                if captcha_bytes:
                    #open('captcha.jpg', 'wb').write(captcha_bytes)
                    fileobj = StringIO.StringIO(captcha_bytes)
                    # read the captcha via deathbycaptcha
                    recaptcha_response_field = read_captcha(fileobj)
                    if recaptcha_response_field:
                        common.logger.info('Have got the captcha content = "%s".' % str(recaptcha_response_field))
                        url = 'https://www.linkedin.com/uas/captcha-submit'
                        post_data = {}
                        captcha_form = xpath.get(html, '//form[@name="captcha"]')
                        for input_name, input_value in re.compile(r']+type="hidden"\s+name="([^<>\"]+)"\s+value="([^<>\"]+)"').findall(captcha_form):
                            post_data[input_name] = input_value
                        post_data['recaptcha_challenge_field'] = recaptcha_challenge_field
                        post_data['recaptcha_response_field'] = recaptcha_response_field                       
                        return D.get(url, data=post_data, read_cache=False)
特别说明:该文章为鲲鹏数据原创文章 ,您除了可以发表评论外,还可以转载到别的网站,但是请保留源地址,谢谢!!(尊重他人劳动,我们共同努力)
☹ Disqus被Qiang了,之前的评论内容都没了。如果您有爬虫相关技术方面的问题,欢迎发到我们的问答平台:http://spider.site-digger.com/
QQ在线客服
欢迎咨询,点击这里给我发送消息。
欢迎咨询,点击这里给我发送消息。