V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
daoluan
V2EX  ›  问与答

需要爬取一个网站内容,需登录和验证码(简单字母数字),怎么破?

  •  
  •   daoluan · 2013-07-05 23:50:38 +08:00 · 9636 次点击
    这是一个创建于 4150 天前的主题,其中的信息可能已经有所发展或是发生改变。
    学校教务系统的网站,最近添加了验证码,不知如何爬取了。

    一个方案:收集验证码图片,降噪处理什么的,标记对应的验证码,生成一个验证码数据集。在需要输入验证码的时候,用图片与数据集中的验证码数据集比较~

    「一个方案」可行么?
    29 条回复    2013-07-18 00:15:17 +08:00
    manoon
        1
    manoon  
       2013-07-06 00:11:08 +08:00
    人工打码。。。
    manoon
        2
    manoon  
       2013-07-06 00:12:23 +08:00   ❤️ 1
    armoni
        3
    armoni  
       2013-07-06 00:55:23 +08:00   ❤️ 1
    http://code.google.com/p/tesseract-ocr/ 英文和数字识别率还行,python库比较成熟
    daoluan
        4
    daoluan  
    OP
       2013-07-06 09:13:54 +08:00
    @manoon 嗯,这个方法不错,但是会产生不必要的流量。

    @denger 的那篇博文,有意思。

    PS:怎么在回复框里 @ 别人啊???
    daoluan
        5
    daoluan  
    OP
       2013-07-06 09:15:57 +08:00
    @armoni 哈哈,非常有意思,写写分享。
    denger
        6
    denger  
       2013-07-06 22:37:38 +08:00 via iPad   ❤️ 1
    有码图片看看么?我可以提供你一些思路。

    @manoon 最近把diz的码给破了( http://www.v2ex.com/t/73685 )" 这个文章仔细看看还是有点老了,不过值得参考
    manoon
        7
    manoon  
       2013-07-06 22:55:24 +08:00
    @denger 对DZ没有丝毫性趣。
    但是对验证码很有兴趣,以后有机会向你多多请教。^_^
    nsxuan
        8
    nsxuan  
       2013-07-06 22:59:29 +08:00 via Android
    地址发来
    daoluan
        9
    daoluan  
    OP
       2013-07-07 00:47:35 +08:00
    @manoon
    @nsxuan
    @denger
    @armoni

    图片的处理解决的差不多来。爬取网页的时候用的是 urllib2,又遇到新的问题:如何让 HTTP header 中的 connection 状态是 keep-alive。

    自己的想法:学校的教务系统好似没有用 cookie 来保持登录状态,所以如果不是 keep-alive,那么即使是登录成功,我也无法陆续读取后来的信息。不知道大家是怎么做的?

    我的想法有没有问题?
    daoluan
        10
    daoluan  
    OP
       2013-07-07 00:55:27 +08:00
    @nsxuan
    @manoon
    @denger
    @armoni

    一个支持「自己的想法」的证据:我在 request 中加入了 cookie,同样在登录成功后无法陆续查看诸多个人信息,相反,返回的是要我重新登录的东东。

    用 wireshark 看了浏览器中发送和接收的 HTTP 和 用 urllib2 发送和接收的 HTTP,两者一模一样,但是得到的结果就是不对。

    怎么破?
    flowerfly
        11
    flowerfly  
       2013-07-07 06:04:12 +08:00
    可参考这一篇
    flowerfly
        12
    flowerfly  
       2013-07-07 06:04:18 +08:00
    msg7086
        13
    msg7086  
       2013-07-07 06:49:27 +08:00
    @daoluan 先用fiddler做重发测试吧。另外keep-alive的HTTP应该也是stateless的。
    daoluan
        14
    daoluan  
    OP
       2013-07-08 21:36:08 +08:00
    @denger http://jwc.scnu.edu.cn/ 这里有图片,谢谢。
    daoluan
        15
    daoluan  
    OP
       2013-07-12 14:45:16 +08:00
    @denger http://jwc.scnu.edu.cn/ 这里有图片,能不能提供一点思路?这种验证码算是简单的吧?
    denger
        16
    denger  
       2013-07-12 18:26:52 +08:00
    @flowerfly 这个文章写的挺不错, 很具参考意义.


    @daoluan 嗯,看上去不难. 如果是我弄的话我会分为下面主要的几步:
    1. 去噪点. 从码图上看字的颜色基本不随机固定色值范围(淺蓝->深蓝), 根据这个规则即可删掉那些随机颜色的噪点. 再根据处理后的效果可考虑是否进行再次处理, 比如将独立的相素点删除(上下左右无相邻的相素点).
    2. 分割. 算是这个码的重难点了. 对于字符之间有粘连的情况如果对识别要求不是特别高(>80%)的话建议忽略该码.其它只有字符间有缝隙的码基本上都能通过扫描线法(自行Google)来搞定.
    3. 分割之后就是为分割之后的字符建立字库了. 起先可人工建立一下字库, 后期使用程序识别+人工纠错的方式建立字库,具体算法为Levenshtein Distance, 参见我的post: http://denger.me/2013/03/hack-sina-weibo-verify-code/
    daoluan
        17
    daoluan  
    OP
       2013-07-12 20:02:28 +08:00
    @flowerfly 推荐的文章收藏了。

    @denger 现在着手手工建立字库。有一个关于效率的问题,因为是在开发微信的应用,微信有个恶心的规定:微信服务器在五秒内收不到响应会断掉连接。所以这就要求处理的速度要够快够迅速。

    不知道上述的匹配过程能不能在 5s 内完成。
    daoluan
        18
    daoluan  
    OP
       2013-07-12 20:19:05 +08:00
    @denger 嗯,Levenshtein Distance 算法就是计算两个字符串的相似度,我看了你的文章后来提到的识别效率问题,无法突破微信的「5 秒」的限制,是个问题。
    zhwei
        19
    zhwei  
       2013-07-12 20:55:46 +08:00
    微信的话, 用户输入验证码算不算一个解决方案

    http://v2ex.com/t/73559#r_672016
    okidogi
        20
    okidogi  
       2013-07-12 22:12:55 +08:00
    # 登录获取cookie,只需要一次获取。
    wget --save-cookies cookies.txt \
    --post-data 'user=username&password=password' \
    http://www.xxx.com

    # 然后加载cookie 就可以随意访问抓取了。。。
    wget --load-cookies cookies.txt \
    -p http://www.xxx.com/article/xxx

    飘过
    Bviews
        21
    Bviews  
       2013-07-12 22:20:00 +08:00
    让用户输入验证码吧。要不然如果验证码比较复杂你的样本库数量大的话,5秒内还要完成抓取解析如果不考虑网络延时的话,可能时间差不多。
    daoluan
        22
    daoluan  
    OP
       2013-07-13 08:27:55 +08:00
    @okidogi 呃。。真不认镇看题,有验证码在那里,cookie 不能直接使用。
    daoluan
        23
    daoluan  
    OP
       2013-07-13 08:30:37 +08:00
    @zhwei 嗯,我已经尝试过了,因为我的 python 服务器是部署在 sae 上,但 sae 不允许写文件,http://sae.sina.com.cn/?m=devcenter&catId=206 PHP 和 java 可以使用 sae 的 TMPFS,但 python 没有这个待遇。

    到底怎么破!
    daoluan
        24
    daoluan  
    OP
       2013-07-13 09:14:23 +08:00
    @zhwei
    @Bviews

    正在考虑用户输入验证码,突破的关键还是前一条回复所说的。请求验证码图片的时候要放入 cookie,不然获取的验证码是没什么用的。
    ccdjh
        25
    ccdjh  
       2013-07-13 13:10:37 +08:00 via Android
    采集同学的数据,自己建立数据库,第一次握手时,先回复一条确认,第二条再回复数据,这样就10秒啦!
    okidogi
        26
    okidogi  
       2013-07-13 17:56:35 +08:00
    @daoluan 是啊,点了回复之后就发现看错题了。囧。
    chrome有个插件,可以将cookie导出成wget可以使用的格式。可以手动输入验证码,然后保存cookie,然后wget。

    https://chrome.google.com/webstore/detail/cookietxt-export/lopabhfecdfhgogdbojmaicoicjekelh?hl=en
    zhwei
        27
    zhwei  
       2013-07-14 10:08:35 +08:00
    @daoluan 我直接保存了用于登陆的对象, 第一次请求的时候调用`pre_login`方法, 返回验证码和请求识别码(eg. md5(datetime) 用户辨认是哪一个请求), 并且将整个对象保存到一个字典中,key为请求识别码, 用户输入验证码后,调用`login`方法, 从字典中`pop`出相应的对象, 模拟登陆.

    登陆流程 https://github.com/zhwei/gotit/blob/gunicorn/code.py#L82-L106
    保存的对象 https://github.com/zhwei/gotit/blob/gunicorn/addons/zf.py
    daoluan
        28
    daoluan  
    OP
       2013-07-17 23:52:53 +08:00
    @zhwei 你确定这能用在微信公众平台上?
    zhwei
        29
    zhwei  
       2013-07-18 00:15:17 +08:00
    @daoluan 需要你自己改一下, 没有做过微信公众平台
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1964 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 36ms · UTC 16:22 · PVG 00:22 · LAX 08:22 · JFK 11:22
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.