推荐学习书目
› 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
wsds
V2EX  ›  Python

Python 中怎么执行 js?

  •  
  •   wsds · Jun 11, 2018 · 8182 views
    This topic created in 3068 days ago, the information mentioned may be changed or developed.

    场景:爬虫 遇到的问题:获取页面隐藏的 token 节点,难道通过接口爬的东西,还要去自动化打开网页,取到 token,再塞进接口里边??

    2 个问题: 1、python 如何执行 js 2、这种场景的问题,是怎么解决的?难道真要通过 selenium 取打开网页,去找到 token,再回过去把取的值,放到接口里边用?

    Supplement 1  ·  Jun 11, 2018

    费劲获取 csrf-token 也没用,它这个还要验证 cookie,好强势的防爬措施,至少把我拦在门外了,不知道各位如何?

    Cookie: XSRF-TOKEN=eyJpdiI6IlpTM2JYUUdWeVN2XC9iSHdYNFNTSGFRPT0iLCJ2YWx1ZSI6IjhMTzVCM3ZRcDFaNE40TmRcL3BURjJNKzZ2QjRQT2NSaEFaQUVYTmlVUGZTMzRZdFdRYWNabE9wMnFBdytXdERvRWIzM1RPemY1eTh0R3d0cWtqMjNUUT09IiwibWFjIjoiZjVkNzRhM2Y4NjE4MWZkYWRlODQ5Y2ZjMjk4NGQ4MWJlNGNhMWNlYWM3YTMwYjQ0YTljNTNjNzY3ODA4Yjk3YyJ9; laravel_session=eyJpdiI6Ik1EQ3lcL205VUF1dzV5a1J0eVhFR1RBPT0iLCJ2YWx1ZSI6InZJMkROTDBaMXhDNGFpU2loXC92d0g1WWZFUFlNc0xDYzZicXF1TWc4bHRzaERYdUs0VWR5NlVCODUyWWNrY2FqNHZzbHQ1aUFZVURjcGtiZTlWczJOZz09IiwibWFjIjoiYTZkMmJjN2U0MTdiYzgzZDE1NzZhMjU5ZjE2ZjA5NWJmZTUzYzNmOTZlY2RkOWVkNWFjNjdhYjM2OTMxNDZmNiJ9
    
    34 replies  •  2018-06-15 09:30:31 +08:00
    est
    est
    Jun 11, 2018
    1
    纯 js 没有 DOM 的,你考虑清楚哦。
    LaFayette
    LaFayette
    Jun 11, 2018 via iPhone
    2
    用 splash
    wly19960911
    wly19960911
    Jun 11, 2018
    4
    解析 DOM,然后 xpath 直接取页面的数据不行吗。我记得 python 不是提供的吗?又不是 JS 渲染的页面,不需要 selenium。
    rabbbit
    rabbbit
    Jun 11, 2018
    5
    import execjs
    execjs.eval()
    wsds
    wsds
    OP
    Jun 11, 2018
    6
    @wly19960911 python 可以解析 DOM 吗,通过 bs4?
    DonaidTrump
    DonaidTrump
    Jun 11, 2018 via iPhone
    7
    读一下 JS 逻辑,用 Python 实现一下就好了,不必非要执行 JS
    wsds
    wsds
    OP
    Jun 11, 2018
    8
    @tulongtou 就是要在 dom 中取值,python 能做到?
    wly19960911
    wly19960911
    Jun 11, 2018
    9
    @tulongtou #7 我不了解 python 最近想试试爬虫玩玩,看了下 bs4 的介绍应该没什么问题,主要你搞错了问题。

    你运行 JS 只是为了获取 html 的值的话没什么意义的。本身 JS 有意义的在于需要根据各种事件和功能去执行业务流程,去修改 DOM 只是一个必要的流程,不管哪个语言都有库解析 XML 和 HTML。不需要执行 JS 都可以
    wsds
    wsds
    OP
    Jun 11, 2018
    10
    @wly19960911 是这个意思,但我只能想到用 js 去取啊,还有其他 方法 吗
    DonaidTrump
    DonaidTrump
    Jun 11, 2018 via iPhone
    11
    @wly19960911 为什么是艾特我?
    wly19960911
    wly19960911
    Jun 11, 2018
    12
    @tulongtou #11 抱歉 AT 错了,
    wly19960911
    wly19960911
    Jun 11, 2018
    13
    @wsds #10 你刚刚说的 BS4 的库应该没问题,你可以看看各种教程。
    hahastudio
    hahastudio
    Jun 11, 2018
    14
    如果这个值写在了 HTML 里,比如 <input name="token" type="hidden" value="blablabla"> 这样的,可以用 bs4,甚至你直接用 XPath,正则什么的都行的
    wsds
    wsds
    OP
    Jun 11, 2018
    15
    @hahastudio
    <input type="hidden" name="_token" value="UlORUHsXUBI7YKg2h73u8pEaWyqDhYioSa1ZYwUK">
    取这个 value 的值
    wsds
    wsds
    OP
    Jun 11, 2018
    16
    @hahastudio 现在的问题是,我 requests.get("http://szjw.changsha.gov.cn/ywcx/"),返回的 dom 中,找不到这个 input
    好尴尬
    just1
    just1
    Jun 11, 2018 via Android
    17
    遇到过相同的问题,最后我选择了写 nodejs 脚本
    hahastudio
    hahastudio
    Jun 11, 2018
    18
    @wsds 因为你想要的这个 token 是 iframe 里的
    <iframe id="Frame_Content" src="http://www.cszjw.net/preselllicence" frameborder="0" scrolling="auto" style="width: 100%; height:100%; min-height:600px;"></iframe>
    你打开 http://www.cszjw.net/preselllicence 就有了
    wsds
    wsds
    OP
    Jun 11, 2018
    19
    @hahastudio 在 iframe 也没关系吧,requests.get()不是返回所有的 html 吗?
    wplct
    wplct
    Jun 11, 2018
    20
    我也是最后选择了 node js 写了个 web 服务调用
    在脚本上模拟一些环境,如
    var navigator = {};
    navigator.userAgent = "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36"
    navigator.vendor = "Google Inc.";
    // 电池状态相关
    navigator.getBattery = function () {
    var battery = {
    charging: true,
    chargingTime: 0,
    dischargingTime: Infinity,
    level: 1,
    onchargingchange: null,
    onchargingtimechange: null,
    ondischargingtimechange: null,
    onlevelchange: null
    };
    return new Promise(function (resolve, reject) {
    resolve(battery)
    });
    };
    然后在脚本后面开个服务器
    // 导入 koa,和 koa 1.x 不同,在 koa2 中,我们导入的是一个 class,因此用大写的 Koa 表示:
    const Koa = require('koa');
    // const koaBody = require('koa-body');
    // 创建一个 Koa 对象表示 web app 本身:
    const app = new Koa();
    // app.use(koaBody());
    // 对于任何请求,app 将调用该异步函数处理请求:
    app.use(async (ctx, next) => {
    await next();
    console.log(ctx.request.body)
    // const body = ctx.request.body;
    // if(!body.href){
    // body.href = ''
    // }
    ctx.response.type = 'text/html';

    ctx.response.body = get_isg('');
    });

    // 在端口 3000 监听:
    app.listen(3000);
    console.log('app started at port 3000...');
    hahastudio
    hahastudio
    Jun 11, 2018
    21
    @wsds 如果你是这么认为的,我觉得你需要看更多的东西了。。。
    kevanbin
    kevanbin
    Jun 11, 2018
    22
    ```
    from requests_html import HTMLSession
    def getToken():
    session = HTMLSession()
    url = 'http://www.cszjw.net/preselllicence'
    token = session.get(url).html.find('input[name="_token"]')[0].attrs['value']
    return token
    ```
    wsds
    wsds
    OP
    Jun 11, 2018
    23
    @kevanbin 为什么这个页面用这个方法 不行? http://szjw.changsha.gov.cn/ywcx/
    mitnick
    mitnick
    Jun 11, 2018
    24
    Leigg
    Leigg
    Jun 11, 2018 via iPhone
    25
    pyv8
    param
    param
    Jun 11, 2018 via Android
    26
    @wplct nodejs 你写个脚本调用不好吗
    Zzdex
    Zzdex
    Jun 11, 2018
    27
    可以用 execjs
    Alpha
    Alpha
    PRO
    Jun 11, 2018
    28
    phatomjs 就可以解决问题
    congeec
    congeec
    Jun 11, 2018 via iPhone
    29
    PyV8 老了,用 py_mini_racer
    flowfire
    flowfire
    Jun 11, 2018 via iPhone
    30
    headless chrome 了解一下
    kevanbin
    kevanbin
    Jun 12, 2018
    31
    @wsds iframe 中的代码,无法在网页源代码中得到
    wsds
    wsds
    OP
    Jun 12, 2018
    32
    @kevanbin 了解了,感谢
    beforeuwait
    beforeuwait
    Jun 14, 2018
    33
    phantomJS 就可以了啊
    我有个类似的项目,一样的 js 算出一个 token 和一个 t,然后放到 cookie 里。
    在拿到 js 后,写一个接收函数,然后 phantom 执行,输出 js 里的 token 和 t,然后请求
    wsds
    wsds
    OP
    Jun 15, 2018
    34
    @beforeuwait 不知道算的,从前端拿到 token,没有 cookie 的话,也是请求不成功的
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Privacy   ·   Solana   ·   1521 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 68ms · UTC 19:12 · PVG 03:12 · LAX 11:12 · JFK 14:12
    ♥ Do have faith in what you're doing.