V2EX = way to explore
V2EX 是一个关于分享和探索的地方
Sign Up Now
For Existing Member  Sign In
推荐学习书目
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
strahe
V2EX  ›  Python

请教一个爬虫问题

  •  
  •   strahe · Jul 4, 2016 · 5102 views
    This topic created in 3584 days ago, the information mentioned may be changed or developed.

    想要抓取一个网站的数据,但是网站好像做了防爬虫处理,有什么方法可以绕过这个,爬到数据.

    网址:https://www.bw.com

    谢谢.

    31 replies    2016-07-05 15:01:48 +08:00
    b821025551b
        1
    b821025551b  
       Jul 4, 2016
    貌似识别 js 引擎吧,在浏览器里写 js 。。。
    mutoulbj
        2
    mutoulbj  
       Jul 4, 2016
    需要爬哪些个数据有防爬?
    比如算力页面:数据在 https://www.bw.com/pool/btcIndexChartsData?type=2https://www.bw.com/pool/ajaxBlocks?coint=btc 两个请求下就可得到。


    没说要什么数据如何分析?
    strahe
        3
    strahe  
    OP
       Jul 4, 2016
    @mutoulbj 我只是举个例子,就比如说 https://www.bw.com/pool/btcIndexChartsData?type=2 这个链接,如何抓取?
    mutoulbj
        4
    mutoulbj  
       Jul 4, 2016
    @strahe 这请求一次不就得到数据了么?你说的怎么抓取是什么意思?
    chendajun
        5
    chendajun  
       Jul 4, 2016
    @strahe requests 拿到源码,再通过 json 或正则提取需要的元素即可
    b821025551b
        6
    b821025551b  
       Jul 4, 2016
    @mutoulbj
    @chendajun

    你们回答问题之前先用 curl 看看能不能正确取到数据好么。
    strahe
        7
    strahe  
    OP
       Jul 4, 2016
    @mutoulbj
    @chendajun 你俩实际请求过吗? 别用浏览器打开
    b821025551b
        8
    b821025551b  
       Jul 4, 2016
    貌似 python 有模拟 js 引擎的库,简单的搜一下,比如这个: Spidermonkey
    http://www.newsmth.net/nForum/#!article/Python/57476
    另外如果找到好的解决方案请楼主回复一下 :D
    binux
        9
    binux  
       Jul 4, 2016
    @strahe
    你浏览器访问一次拿到 cookie ,再用 cookie 爬不就好了。你会什么就用什么搞呗。
    strahe
        10
    strahe  
    OP
       Jul 4, 2016
    @binux 把包括 cookie 在内的 header 全部拷贝近程序也不行
    binux
        11
    binux  
       Jul 4, 2016
    @strahe ip 相同吗?
    strahe
        12
    strahe  
    OP
       Jul 4, 2016
    @b821025551b 我试下,今天试了几个都不好使.
    yanyuan2046
        14
    yanyuan2046  
       Jul 4, 2016
    最简单的办法
    1 、打开 chrome 开发者工具
    2 、请求 https://www.bw.com/pool/btcIndexChartsData?type=2
    3 、把抓到的 http header 全部添加到你的 python 爬虫中
    4 、你的爬虫跟浏览器就是一模一样了
    5 、如果 header 是动态的(不同请求,某个 http header 的值在变化,就分析这个值是怎么来的)
    csdreamdong
        15
    csdreamdong  
       Jul 4, 2016
    @yanyuan2046 同意。
    csdreamdong
        16
    csdreamdong  
       Jul 4, 2016
    curl 'https://www.bw.com/pool/btcIndexChartsData?type=2' -H 'Pragma: no-cache' -H 'Accept-Encoding: gzip, deflate, sdch, br' -H 'Accept-Language: zh-CN,zh;q=0.8' -H 'Upgrade-Insecure-Requests: 1' -H 'User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.103 Safari/537.36' -H 'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8' -H 'Cache-Control: no-cache' -H 'Cookie: __jsluid=5431640c14c76916ab42ab965018aedd; __jsl_clearance=1467627242.423|0|a%2FIkug0lf8VyLrxcW4zgJNNtttE%3D; Hm_lvt_bb4a4d5e0b7e0cdff02975c9129fc66c=1467627246; Hm_lpvt_bb4a4d5e0b7e0cdff02975c9129fc66c=1467627246' -H 'Connection: keep-alive' --compressed
    strahe
        17
    strahe  
    OP
       Jul 4, 2016
    @yanyuan2046
    @csdreamdong
    定时任务这样就行不通了
    csdreamdong
        18
    csdreamdong  
       Jul 4, 2016
    @strahe 0 0 还没做实验,但从 header 上来看。唯一能影响的就是 cookies 。
    每次请求钱,先访问一次 https://www.bw.com ,拿到 cookies 。。再请求 。应该可行。。。
    b821025551b
        19
    b821025551b  
       Jul 4, 2016
    @yanyuan2046
    @csdreamdong

    你们忽略了一点,爬虫和浏览器的很大区别是,大部分爬虫没有 js 引擎的支持,而这个网站很可能是启用了 js 引擎校验。
    @csdreamdong 既然你贴出了 curl 的方法,那试着去实际请求一下。
    z333d
        20
    z333d  
       Jul 4, 2016 via Android
    大概这么一个步骤(Python):
    1. 打开 chrome 开发者工具,选到 network 面板,如果页面已经渲染过,则再刷新一下
    2. 找到这个页面的请求链接,右键 copy as cUrl
    3. 把拷贝的内容贴到 http://curl.trillworks.com ,选择 Python ,转换得到的代码在你安装了 requests 这个包的前提下便可以运行
    建议可以用 ipython notebook 进行 cookies , headers 字段的选择
    aeshfawre
        21
    aeshfawre  
       Jul 4, 2016
    你们这群人啊,根本就没去试,这网站是很特殊,发送的 header 完全一样却得不到一样的结果.
    作为一个爬虫老司机,对这网站表示值得深入研究.
    以前遇到过类似一样的站点,https 访问的时候连接的加密设置不同引起的
    aeshfawre
        22
    aeshfawre  
       Jul 4, 2016
    我可以肯定不是因为 cookie 引起的,用 burpsuite 重复发送是可以的,但是用 python 就不行,这与我以前遇到的站点类似.
    当然这站点 cookie 会过期,这不是重点.
    binux
        23
    binux  
       Jul 4, 2016
    @aeshfawre 什么很特殊,值得深入研究啊,就是个加速乐的 CDN 而已。
    写一个 cookie , js 再算另一个,有时间限制,和 IP 环境绑定。 HTTP 协议就那么点东西,和你用什么发请求一点关系都没有。
    怕麻烦就复制 cookie ,不怕麻烦就上 js 引擎。
    strahe
        24
    strahe  
    OP
       Jul 4, 2016
    @aeshfawre 老司机研究一下,有结果了告知一下啊
    aeshfawre
        25
    aeshfawre  
       Jul 5, 2016   ❤️ 3
    好吧,我错了,其实这也一样只是 cookie 的问题.作为老司机,我必须再练下手,下面是解决的步骤:

    准备工作:ubuntu 系统
    1:首先安装 phantomjs ubuntu 系统下 最新版 http://phantomjs.org/download.html
    cd /usr/local/share/
    sudo wget https://bitbucket.org/ariya/phantomjs/downloads/phantomjs-2.1.1-linux-x86_64.tar.bz2
    sudo tar jxvf phantomjs-2.1.1-linux-x86_64.tar.bz2
    sudo ln -s /usr/local/share/phantomjs-2.1.1-linux-x86_64 /usr/local/share/phantomjs
    sudo ln -s /usr/local/share/phantomjs/bin/phantomjs /usr/local/bin/phantomjs
    which phantomjs

    2:获取要被执行的 js, 创建一个 python 文件如下内容:
    import requests
    import commands
    html=requests.get('https://www.bw.com/pool/btcIndexChartsData?type=2')
    cookie1=html.cookies['__jsluid'] #第一个 cookie
    js = html.text.replace("<script>", '')
    js = js.replace("</script>", '')
    js = js.replace("eval", 'console.log')
    js = js+'phantom.exit()'
    f = open('getcookie.js', "w+")
    f.write(js)
    f.close()
    status, output = commands.getstatusoutput('phantomjs getcookie.js') #第一次解析获得用来生成 cookie 的 js 代码
    idx=output.find('{};')
    output2=output[idx+3:] #去除头部
    idx=output2.find('setTimeout')
    output2=output2[0:idx] #去除尾部
    output2=output2+'console.log(dc);phantom.exit();'
    f = open('getcookie.js', "w+")
    f.write(output2)
    f.close()
    status, cookie2 = commands.getstatusoutput('phantomjs getcookie.js') #第二次执行 js 代码获得 cookie
    cookie2=cookie2.replace('__jsl_clearance=','')
    #用 cookie1 和 cookie2 去获取真正的数据

    cookie = {'__jsluid':cookie1 , '__jsl_clearance':cookie2}
    html=requests.get('https://www.bw.com/pool/btcIndexChartsData?type=2',cookies=cookie)
    print html.text
    543400
        26
    543400  
       Jul 5, 2016
    这头像好像我老师 你是珠海的?
    strahe
        27
    strahe  
    OP
       Jul 5, 2016
    @543400 一个头像也可以? 杭州
    strahe
        28
    strahe  
    OP
       Jul 5, 2016
    @aeshfawre 直接从它返回的 js 中找不出来 cookie 吗?必须要用 phantomjs?
    aeshfawre
        29
    aeshfawre  
       Jul 5, 2016
    @strahe 可以啊,你将这段 js 看懂,然后用自己的语言编写出同样功能的代码来.
    cha1
        30
    cha1  
       Jul 5, 2016
    @aeshfawre 里面有一段 js 代码,恶心到我了。。怪不得我直接用 Selenium+PhantomJS 好像被卡住了一样。。。

    while (window._phantom || window.__phantomas) {
    };
    aeshfawre
        31
    aeshfawre  
       Jul 5, 2016
    @zqhong 嗯, 解决这个站点不想利用 js 引擎,那就必须将这 js 翻译出来,写出同样功能的代码 , 难度有点高.
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Solana   ·   4919 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 56ms · UTC 09:59 · PVG 17:59 · LAX 02:59 · JFK 05:59
    ♥ Do have faith in what you're doing.