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

Python 模拟浏览器请求,怎么保持前一个 get 和后一个 post 是对同一个页面进行处理呢?

  •  
  •   Ruohua3kou · 2018-05-16 09:38:16 +08:00 · 4888 次点击
    这是一个创建于 2380 天前的主题,其中的信息可能已经有所发展或是发生改变。

    如题..需要用到什么模块呢? requests 的话后一次 POST 是又一次对 URL 的请求了,不知道该怎么实现对上一次 GET 请求返回的页面进行请求呢?

    第 1 条附言  ·  2018-05-16 13:58:58 +08:00
    原题目问题利用 session 解决了。。
    现在是不知道什么原因导致 post 响应 500 (未用 session 前因为 post 的某值与上一次 get 的某值不符合被认为非法访问)
    该脚本原本是打算写一个自动答题的脚本
    ===================================
    import requests
    import re
    import json

    ses = requests.Session()
    ....
    字数显示,具体已在楼中回复
    ....
    headers = {
    'host': '112.74.185.30:8080',
    'Accept': 'application/json',
    'X-Requested-With': 'XMLHttpRequest',
    'Accept-Language': 'zh-cn',
    'Accept-Encoding': 'gzip, deflate',
    'Content-Type': 'application/json; charset=UTF-8',
    'Origin': 'ht [防检测] tp://112.74.185.30:8080',
    'Content-Length': '57',
    'User-Agent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 11_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/11.0 Mobile/15E148 Safari/604.1',
    'Referer': 'h [防检测] ttp://112.74.185.30:8080/yiban-web/stu/toSubject.jht [防检测] ml?cour [防检测] seId=8',
    'DNT': '1',
    'Connection': 'keep-alive',
    'Cookie': 'JSESSIONID=0D7E4E12942F878489DEA60B97561F8F',
    }

    data={
    'answer':'A',
    'courseId':'8',
    'uuid':''
    }
    data['uuid'] = uuid[0]
    data['answer']=answer[0]

    res = ses.post(url='ht [防检测] tp://112.74.1 [防检测] 85.30:8080/yiban-web/stu/changeSituation.jht [防检测] ml',
    headers=headers, data=json.dumps(data))
    print(res.text)

    ===========================================
    利用 session(),使上次 get 和下次 post 成功对同一个页面请求了,但是第二次的 post 从被验证为非法访问变成了响应头 500.....(应该是 UUID 对上了所以验证为合法访问了,但是不知道什么原因出现 500 错误) 看了下,第一次 GET 到的页面中提交函数是用 muj.ajax (我不太懂 js。。),
    function changeSituation(answer){

    var data={'answer':answer,'courseId':baseInfoData.data.subject.courseId,'uuid':baseInfoData.data.uuid};

    mui.ajax({

    url: '/yiban-web/stu/changeSituation.jhtml',

    async: true,

    cache: false,

    type: 'post',

    data:data,

    dataType: 'json',
    …………………………
    第 2 条附言  ·  2018-05-16 15:24:58 +08:00
    第二次修改之后:
    在第二个 headers 里添加 cookies 字典时,响应:{"data":{},"isSuccess":false,"message":"非正常访问!答题失败"}

    不添加 cookies
    第 3 条附言  ·  2018-05-16 15:26:04 +08:00
    不小心点了提交。。
    接上,不在 headers 里添加 cookie 时,返回响应 500 Internal Server Error
    20 条回复    2018-05-17 04:28:04 +08:00
    wisej
        1
    wisej  
       2018-05-16 09:50:57 +08:00
    如果你没有禁止重定向的话,我猜你是想要 r.url 这个值?
    302766392
        2
    302766392  
       2018-05-16 09:52:58 +08:00   ❤️ 1
    可以建立一个会话连接
    s = requests.session()
    g_res = s.get(url, headers, params)
    p_res = s.post(url, headers, data)
    shuax
        3
    shuax  
       2018-05-16 09:53:34 +08:00   ❤️ 1
    我猜你是想用 session
    Ruohua3kou
        4
    Ruohua3kou  
    OP
       2018-05-16 09:55:26 +08:00
    import requests

    # ses = requests.Session()
    # first_url = "http://112.74.185.30:8080/yiban-web/stu/toSubject.jhtml?courseId=8"
    # first_headers={
    # 'host': '112.74.185.30:8080',
    # 'Accept-Encoding': 'gzip, deflate',
    # 'Upgrade-Insecure-Requests': '1',
    # 'User-Agent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 11_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/11.0 Mobile/15E148 Safari/604.1',
    # 'Referer': 'http://112.74.185.30:8080/yiban-web/stu/toCourse.jhtml',
    # 'DNT': '1',
    # 'Connection': 'keep-alive',
    # }
    # first_cookies = {'JSESSIONID': '0D7E4E12942F878489DEA60B97561F8F'}

    # res=ses.get(url=first_url,cookies=first_cookies)

    headers = {
    'host': '112.74.185.30:8080',
    'Accept': 'application/json',
    'X-Requested-With': 'XMLHttpRequest',
    'Accept-Language': 'zh-cn',
    'Accept-Encoding': 'gzip, deflate',
    'Content-Type': 'application/x-www-form-urlencoded',
    'Origin': 'http://112.74.185.30:8080',
    'Content-Length': '57',
    'User-Agent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 11_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/11.0 Mobile/15E148 Safari/604.1',
    'Referer': 'http://112.74.185.30:8080/yiban-web/stu/toSubject.jhtml?courseId=8',
    'DNT': '1',
    'Connection': 'keep-alive',
    'Cookie': 'xxx',
    }

    data={
    'answer':'A',
    'courseId':'8',
    'uuid':'EB180D559F46426DAD2E9916DEA501DBxxxxxx'
    }

    res = requests.post(url='http://112.74.185.30:8080/yiban-web/stu/changeSituation.jhtml?_=1526406696684',headers=headers, data=data)
    print(res.text)


    ====================================
    注释里 GET 得到的页面里,有个 UUID 在一段 JS 代码里,然后我想得到这个 UUID 并且加到 DATA 中去 POST 刚刚 GET 得到的内容
    manzhiyong
        5
    manzhiyong  
       2018-05-16 09:56:01 +08:00   ❤️ 1
    webdriver 了解一下
    Ruohua3kou
        6
    Ruohua3kou  
    OP
       2018-05-16 09:56:08 +08:00
    @wisej 新回复贴了代码,是想得到 GET 页面生成的一段 KEY 值
    Ruohua3kou
        7
    Ruohua3kou  
    OP
       2018-05-16 09:56:23 +08:00
    谢谢楼上各位,我试试这俩方法。。
    Hopetree
        8
    Hopetree  
       2018-05-16 09:56:53 +08:00   ❤️ 1
    session 就行
    wisej
        9
    wisej  
       2018-05-16 10:05:23 +08:00   ❤️ 1
    @Ruohua3kou 我一般是正则提取
    Mavious
        10
    Mavious  
       2018-05-16 12:15:32 +08:00
    session 是用来保持 cookies 的,让 URL1 携带着 cookies 到下一个 URL2 里去。感觉不适用于 LZ 的要求。
    MonoLogueChi
        11
    MonoLogueChi  
       2018-05-16 12:47:56 +08:00 via Android
    我也有遇到过这种问题,需要先获取页面生成的随机数,然后随机数要提交到表单里
    YenvY
        12
    YenvY  
       2018-05-16 13:20:25 +08:00
    没懂,就算用浏览器来真的不也是两次请求吗
    Ruohua3kou
        13
    Ruohua3kou  
    OP
       2018-05-16 13:53:26 +08:00
    import requests
    import re
    import json

    ses = requests.Session()
    first_url = "htt [防检测] p://112.74.185.30:8080/yiban-web/stu/toSubject.jh [防检测] tml?courseId=8"
    first_headers={
    'host': '1 12.74.185.30:8080',
    'Accept-Encoding': 'gzip, deflate',
    'Upgrade-Insecure-Requests': '1',
    'User-Agent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 11_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/11.0 Mobile/15E148 Safari/604.1',
    'Referer': 'h [防检测] ttp://112.74.185.30:8080/yiban-web/stu/toCourse.jht [防检测] ml',
    'DNT': '1',
    'Connection': 'keep-alive',
    }
    first_cookies = {'JSESSIONID': 'E3857AA04B846ED5414BA5EE0421617F'}

    res=ses.get(url=first_url,cookies=first_cookies)

    text=res.text
    answer = re.findall(r'"answer":\"(.*?)\"',text)
    uuid = re.findall(r'baseInfoData.data.uuid = \'(.*)\'', text)

    headers = {
    'host': '112.74.185.30:8080',
    'Accept': 'application/json',
    'X-Requested-With': 'XMLHttpRequest',
    'Accept-Language': 'zh-cn',
    'Accept-Encoding': 'gzip, deflate',
    'Content-Type': 'application/json; charset=UTF-8',
    'Origin': 'ht [防检测] tp://112.74.185.30:8080',
    'Content-Length': '57',
    'User-Agent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 11_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/11.0 Mobile/15E148 Safari/604.1',
    'Referer': 'h [防检测] ttp://112.74.185.30:8080/yiban-web/stu/toSubject.jht [防检测] ml?cour [防检测] seId=8',
    'DNT': '1',
    'Connection': 'keep-alive',
    'Cookie': 'JSESSIONID=0D7E4E12942F878489DEA60B97561F8F',
    }

    data={
    'answer':'A',
    'courseId':'8',
    'uuid':''
    }
    data['uuid'] = uuid[0]
    data['answer']=answer[0]

    res = ses.post(url='ht [防检测] tp://112.74.1 [防检测] 85.30:8080/yiban-web/stu/changeSituation.jht [防检测] ml',
    headers=headers, data=json.dumps(data))
    print(res.text)

    ===========================================
    利用 session(),使上次 get 和下次 post 成功对同一个页面请求了,但是第二次的 post 从被验证为非法访问变成了响应头 500.....(应该是 UUID 对上了所以验证为合法访问了,但是不知道什么原因出现 500 错误) 看了下,第一次 GET 到的页面中提交函数是用 muj.ajax (我不太懂 js。。),
    function changeSituation(answer){

    var data={'answer':answer,'courseId':baseInfoData.data.subject.courseId,'uuid':baseInfoData.data.uuid};

    mui.ajax({

    url: '/yiban-web/stu/changeSituation.jhtml',

    async: true,

    cache: false,

    type: 'post',

    data:data,

    dataType: 'json',
    …………………………

    =============================================
    不知道现在有什么解决办法呢,望请教!
    LeGendAI
        14
    LeGendAI  
       2018-05-16 13:53:53 +08:00
    如果 KEY 是服务器返回的值,直接 get 一次页面,再用正则之类的提取就行了;如果 KEY 是本地生成的,找到它的生成逻辑自己再实现一下就 ok 了。get 和 post 之间不需要有关系啊。
    LeGendAI
        15
    LeGendAI  
       2018-05-16 13:57:12 +08:00
    @Ruohua3kou 刚遇到 过一个 5xx 错误,可能你需要把 post 里面的参数名从 data 换成 json
    zyqf
        16
    zyqf  
       2018-05-16 14:53:46 +08:00 via Android
    第一:headers 一般不需要写死 cookie,Session() 会自动帮你维护 。
    第二:注意下表单是否有类似 csrf_token 的值。

    另外注意下排版问题。希望能帮到你。
    Ruohua3kou
        17
    Ruohua3kou  
    OP
       2018-05-16 15:18:54 +08:00
    @LeGendAI 刚试了下,data 改成 json=json.dumps(data)了,TAT 还是不行
    Ruohua3kou
        18
    Ruohua3kou  
    OP
       2018-05-16 15:20:31 +08:00
    @zyqf 感谢提醒 ! 但是没找到类似 csrf_token 的值,第一次发帖,我会注意排版的。。
    chrisyunhua
        19
    chrisyunhua  
       2018-05-16 17:46:24 +08:00
    .post(url, json=dict)
    xiaol825
        20
    xiaol825  
       2018-05-17 04:28:04 +08:00
    fiddler 抓包看一下,对比下自己代码模拟发送的请求和真实的浏览器发送的请求的区别。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   5929 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 24ms · UTC 02:36 · PVG 10:36 · LAX 18:36 · JFK 21:36
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.