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

爬虫请教,请问如何爬 "http://www.kuaidaili.com/" 的数据

  •  
  •   odirus · 2016-04-07 18:30:21 +08:00 · 6446 次点击
    这是一个创建于 3142 天前的主题,其中的信息可能已经有所发展或是发生改变。
    经过测试

    ( 1 )模拟浏览器 header 不行;
    ( 2 )使用 phantomjs 也不行;

    "http://www.yundun.com/" 这网站提供的防爬虫设计。

    求一个简单易行的思路,我也不知道怎么才能突破反爬虫规则
    23 条回复    2016-05-25 00:07:51 +08:00
    popok
        1
    popok  
       2016-04-07 18:46:23 +08:00
    什么问题?
    频率限制还是什么的??

    这网站默认 gzip
    popok
        2
    popok  
       2016-04-07 18:48:51 +08:00   ❤️ 2
    这个 yundun 只是一个 cdn 而已吧,你抓不到明文数据应该就是返回的数据都是 gzip 压缩的,你本地再解压一下,就能处理了
    naomhan
        3
    naomhan  
       2016-04-07 18:49:11 +08:00   ❤️ 1
    没有吧 我记得 kuaidaili 很好爬的
    binux
        4
    binux  
       2016-04-07 18:56:15 +08:00   ❤️ 1
    使用 phantomjs 没有问题
    gimp
        5
    gimp  
       2016-04-07 19:08:23 +08:00   ❤️ 1
    #!/bin/env python
    # -*- encoding:utf-8 -*-
    from selenium import webdriver
    import time

    driver = webdriver.Firefox()
    driver.set_window_size(1366, 768)
    driver.get("http://www.kuaidaili.com/")
    time.sleep(10)
    bodyStr= driver.find_element_by_tag_name("table").get_attribute("innerHTML")
    print bodyStr

    很好抓呀,当然,要是觉得 time.sleep(10)太 low

    #!/bin/env python
    # -*- encoding:utf-8 -*-
    from selenium import webdriver
    from selenium.webdriver.common.by import By
    from selenium.webdriver.support.ui import WebDriverWait
    from selenium.webdriver.support import expected_conditions as EC

    driver = webdriver.Firefox()
    driver.set_window_size(1366, 768)
    driver.get("http://www.kuaidaili.com/")
    wait = WebDriverWait(driver, 10)
    wait.until(
    EC.presence_of_element_located((By.CSS_SELECTOR, ".table-bordered"))
    )
    bodyStr= driver.find_element_by_tag_name("table").get_attribute("innerHTML")
    print bodyStr
    UnisandK
        6
    UnisandK  
       2016-04-07 19:09:39 +08:00   ❤️ 1

    浏览器清了 cookie 刷新就这效果,请求里没看到特殊的东西,应该先是根据 IP 来的

    那破玩意还是加了密的。。实质是一个跳转


    要爬的话,你在服务器上装个 node.js 来获取 yundun=后边的参数吧。。
    odirus
        7
    odirus  
    OP
       2016-04-07 19:15:52 +08:00
    @popok 恩恩,谢谢。主要是我这边一直提示的 HTTP CODE = 521
    odirus
        8
    odirus  
    OP
       2016-04-07 19:18:01 +08:00
    @UnisandK 我这边主要是提示 521 错误。。
    UnisandK
        9
    UnisandK  
       2016-04-07 19:25:25 +08:00   ❤️ 1
    @odirus 521 返回的就是中间那一串加密了的 JS ,实质上就是一句跳转,主要目的是确认你有 JS 的执行环境,以此来剔除爬虫。。
    odirus
        10
    odirus  
    OP
       2016-04-07 19:54:29 +08:00
    @UnisandK 手动感谢。
    odirus
        11
    odirus  
    OP
       2016-04-07 19:57:17 +08:00
    @binux 咨询一下,为什么我执行 "curl -H 'Accept-Encoding:gzip' http://www.kuaidaili.com"后,对方有时返回原文、有时是 gzip 格式呢?是对方没遵守 HTTP 相关协议,还是我自己忽略了什么?谢谢


    @popok
    @naomhan
    @binux
    @gimp
    @UnisandK

    受益匪浅,不胜感激。
    sohoer
        12
    sohoer  
       2016-04-07 20:14:03 +08:00
    521 不是标准的 http status code ,是他自定义的,
    浏览器会把他当成 200 解析

    还是 Fiddler 好, chrome 、 ie 都看不到那段 js 加密跳转代码
    popok
        13
    popok  
       2016-04-07 20:34:37 +08:00
    @odirus 他好像确实没遵守协议,不管请求有没有 gzip ,他返回的都是 gzip 压缩过的,至少我随便试了下是这样的
    sohoer
        14
    sohoer  
       2016-04-07 20:39:51 +08:00   ❤️ 1
    JAVA API HttpURLConnection 还不支持 521 拿不到那段源码
    binux
        15
    binux  
       2016-04-07 21:20:36 +08:00   ❤️ 1
    @odirus Accept-Encoding:gzip 并不表示对方一定得返回 gzip
    chinvo
        16
    chinvo  
       2016-04-07 21:24:14 +08:00   ❤️ 1
    解析或执行这段 js ,取得 cookie ,重爬
    sohoer
        17
    sohoer  
       2016-04-07 21:38:32 +08:00   ❤️ 1
    更正一下,看了半天源码发现有 API
    Status >= 400 时可以通过 HttpURLConnection getErrorStream() 获取 InputStream;
    odirus
        18
    odirus  
    OP
       2016-04-08 09:02:49 +08:00
    @sohoer 恩,感谢。以前一直不知道 HTTP CODE 规范的意义,现在遇到浙西问题才恍然大悟,没有规矩不成方圆。
    @binux 恩,谢谢,明白了。
    @chinvo 恩,谢谢,之前在本地执行这段 js 的时候没明白啥意思。谢谢。

    @sohoer 很有专研精神, 3Q
    killerv
        19
    killerv  
       2016-04-08 11:05:47 +08:00
    这个网站的代理坑爹的,以前花钱买过,代理基本上 90%都不能用
    LinJunzhu
        20
    LinJunzhu  
       2016-05-23 23:59:15 +08:00
    @odirus 你好,能请教下关于这个网站的爬取么?

    521 后如何能够拿到 yundun 后的参数呢?

    使用的是 Scrapy 框架
    LinJunzhu
        21
    LinJunzhu  
       2016-05-24 13:41:41 +08:00
    @UnisandK

    你好,能麻烦请教下么?

    我在获得 response 的 JS 代码后
    ```javascript
    window.onload=setTimeout("by(242)", 200);
    function by(OG) {var qo, mo="", no="", oo = [0x0a,0x9a,0x4a,0x01,0x7c,0x13,0xb5,0x4f,0xfd,0x78,0x0f,0x27,0xd6,0xae,0x28,0xfe,0x95,0x50,0x98,0xe8,0x15,0xa7,0x9d,0xd7,0x88,0x1f,0x18,0xf0,0x67,0x3e,0x19,0x33,0xac,0x3b,0x09,0x99,0x87,0x60,0xb5,0x70,0xe7,0x3d,0x85,0x40,0x90,0x08,0xf8,0x66,0x07,0x35,0xb0,0xde,0x17,0x2f,0x27,0xfe,0xd6,0x88,0xf5,0xe7,0xdc,0xea,0x62,0x34,0x01,0xd1,0x7f,0xd0,0x19,0x22];qo = "qo=68; do{oo[qo]=(-oo[qo])&0xff; oo[qo]=(((oo[qo]>>2)|((oo[qo]<<6)&0xff))-99)&0xff;}while(--qo>=2);"; eval(qo);qo = 67; do { oo[qo] = (oo[qo] - oo[qo - 1]) & 0xff; } while (-- qo >= 3 );qo = 1; for (;;) { if (qo > 67) break; oo[qo] = ((((((oo[qo] + 198) & 0xff) + 204) & 0xff) << 5) & 0xff) | (((((oo[qo] + 198) & 0xff) + 204) & 0xff) >> 3);qo++;}po = "";for (qo = 1; qo < oo.length - 1; qo++) if (qo % 6) po += String.fromCharCode(oo[qo] ^ OG);po += "\""; eval("qo=eval;qo(po);");}

    ```

    那这里该如何去解析拿到 yundun 的 id 呢?
    odirus
        22
    odirus  
    OP
       2016-05-24 15:13:20 +08:00
    @LinJunzhu 我没用过 Scrapy 呢,我用的是 selenium + PhamtomJS ,

    那段 JavaScript 代码其实就是重定向的代码,但是我没找到在 Python 中执行 JavaScript 合适的轮子,所以就直接用 PhamtomJS 执行这个页面,当然也会自动运行 JavaScript 代码,然后我就到真实页面了。

    但是我发现这个代理网站很糟糕,所以我就发现了另外一个网站, http://www.freeproxylists.net/。如果你爬这个网站的时候遇到机器人验证,你也搞不定的话,可以再问。
    LinJunzhu
        23
    LinJunzhu  
       2016-05-25 00:07:51 +08:00
    @odirus 感谢回复 :)

    现在解决了这个问题,我的解决方法:

    1 、 Scrapy + selenium + PhamtomJS
    2 、 Scrapy 请求拿到那段 JS 后,修改下那段 JS 执行跳转的代码,拿到要跳转的 link (因为我用的 driver.execute_script( js ) 执行完后没办法自动跳转到指定页面。)
    3 、拿到 link 后就好办了,直接请求。

    另外,发现我拿到的代理压根用不了。。。。。也是醉人。 还想着说稳定的话以后就购买了。

    我去试试你的那个网站,谢谢了。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2713 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 25ms · UTC 15:34 · PVG 23:34 · LAX 07:34 · JFK 10:34
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.