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
strahe
V2EX  ›  Python

请教一个爬虫问题

  •  
  •   strahe · 2016-07-04 16:37:34 +08:00 · 4405 次点击
    这是一个创建于 3097 天前的主题,其中的信息可能已经有所发展或是发生改变。

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

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

    谢谢.

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


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

    你们回答问题之前先用 curl 看看能不能正确取到数据好么。
    strahe
        7
    strahe  
    OP
       2016-07-04 17:31:38 +08:00
    @mutoulbj
    @chendajun 你俩实际请求过吗? 别用浏览器打开
    b821025551b
        8
    b821025551b  
       2016-07-04 17:40:43 +08:00
    貌似 python 有模拟 js 引擎的库,简单的搜一下,比如这个: Spidermonkey
    http://www.newsmth.net/nForum/#!article/Python/57476
    另外如果找到好的解决方案请楼主回复一下 :D
    binux
        9
    binux  
       2016-07-04 17:53:17 +08:00
    @strahe
    你浏览器访问一次拿到 cookie ,再用 cookie 爬不就好了。你会什么就用什么搞呗。
    strahe
        10
    strahe  
    OP
       2016-07-04 17:56:55 +08:00
    @binux 把包括 cookie 在内的 header 全部拷贝近程序也不行
    binux
        11
    binux  
       2016-07-04 17:57:41 +08:00
    @strahe ip 相同吗?
    strahe
        12
    strahe  
    OP
       2016-07-04 17:57:45 +08:00
    @b821025551b 我试下,今天试了几个都不好使.
    yanyuan2046
        14
    yanyuan2046  
       2016-07-04 18:07:39 +08:00
    最简单的办法
    1 、打开 chrome 开发者工具
    2 、请求 https://www.bw.com/pool/btcIndexChartsData?type=2
    3 、把抓到的 http header 全部添加到你的 python 爬虫中
    4 、你的爬虫跟浏览器就是一模一样了
    5 、如果 header 是动态的(不同请求,某个 http header 的值在变化,就分析这个值是怎么来的)
    csdreamdong
        15
    csdreamdong  
       2016-07-04 18:13:14 +08:00
    @yanyuan2046 同意。
    csdreamdong
        16
    csdreamdong  
       2016-07-04 18:15:33 +08:00
    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
       2016-07-04 18:20:32 +08:00
    @yanyuan2046
    @csdreamdong
    定时任务这样就行不通了
    csdreamdong
        18
    csdreamdong  
       2016-07-04 18:28:10 +08:00
    @strahe 0 0 还没做实验,但从 header 上来看。唯一能影响的就是 cookies 。
    每次请求钱,先访问一次 https://www.bw.com ,拿到 cookies 。。再请求 。应该可行。。。
    b821025551b
        19
    b821025551b  
       2016-07-04 18:31:08 +08:00
    @yanyuan2046
    @csdreamdong

    你们忽略了一点,爬虫和浏览器的很大区别是,大部分爬虫没有 js 引擎的支持,而这个网站很可能是启用了 js 引擎校验。
    @csdreamdong 既然你贴出了 curl 的方法,那试着去实际请求一下。
    z333d
        20
    z333d  
       2016-07-04 19:20:43 +08:00 via Android
    大概这么一个步骤(Python):
    1. 打开 chrome 开发者工具,选到 network 面板,如果页面已经渲染过,则再刷新一下
    2. 找到这个页面的请求链接,右键 copy as cUrl
    3. 把拷贝的内容贴到 http://curl.trillworks.com ,选择 Python ,转换得到的代码在你安装了 requests 这个包的前提下便可以运行
    建议可以用 ipython notebook 进行 cookies , headers 字段的选择
    aeshfawre
        21
    aeshfawre  
       2016-07-04 19:27:15 +08:00
    你们这群人啊,根本就没去试,这网站是很特殊,发送的 header 完全一样却得不到一样的结果.
    作为一个爬虫老司机,对这网站表示值得深入研究.
    以前遇到过类似一样的站点,https 访问的时候连接的加密设置不同引起的
    aeshfawre
        22
    aeshfawre  
       2016-07-04 19:31:03 +08:00
    我可以肯定不是因为 cookie 引起的,用 burpsuite 重复发送是可以的,但是用 python 就不行,这与我以前遇到的站点类似.
    当然这站点 cookie 会过期,这不是重点.
    binux
        23
    binux  
       2016-07-04 19:50:06 +08:00
    @aeshfawre 什么很特殊,值得深入研究啊,就是个加速乐的 CDN 而已。
    写一个 cookie , js 再算另一个,有时间限制,和 IP 环境绑定。 HTTP 协议就那么点东西,和你用什么发请求一点关系都没有。
    怕麻烦就复制 cookie ,不怕麻烦就上 js 引擎。
    strahe
        24
    strahe  
    OP
       2016-07-04 20:08:42 +08:00
    @aeshfawre 老司机研究一下,有结果了告知一下啊
    aeshfawre
        25
    aeshfawre  
       2016-07-05 00:55:15 +08:00   ❤️ 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  
       2016-07-05 09:32:35 +08:00
    这头像好像我老师 你是珠海的?
    strahe
        27
    strahe  
    OP
       2016-07-05 09:38:40 +08:00
    @543400 一个头像也可以? 杭州
    strahe
        28
    strahe  
    OP
       2016-07-05 09:40:08 +08:00
    @aeshfawre 直接从它返回的 js 中找不出来 cookie 吗?必须要用 phantomjs?
    aeshfawre
        29
    aeshfawre  
       2016-07-05 09:59:45 +08:00
    @strahe 可以啊,你将这段 js 看懂,然后用自己的语言编写出同样功能的代码来.
    zqhong
        30
    zqhong  
       2016-07-05 14:29:54 +08:00
    @aeshfawre 里面有一段 js 代码,恶心到我了。。怪不得我直接用 Selenium+PhantomJS 好像被卡住了一样。。。

    while (window._phantom || window.__phantomas) {
    };
    aeshfawre
        31
    aeshfawre  
       2016-07-05 15:01:48 +08:00
    @zqhong 嗯, 解决这个站点不想利用 js 引擎,那就必须将这 js 翻译出来,写出同样功能的代码 , 难度有点高.
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   5326 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 44ms · UTC 07:53 · PVG 15:53 · LAX 23:53 · JFK 02:53
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.