【问题标题】:Python :: requests authPython :: 请求身份验证
【发布时间】:2017-01-31 10:43:37
【问题描述】:

我正在尝试使用 BeautifulSoup 抓取网站。该网站需要登录。

https://www.bahn.de/p/view/meinebahn/login.shtml

研究网络我知道获得授权的一种正确方法是使用requests

我的代码如下:

url = 'https://www.bahn.de/p/view/meinebahn/login.shtml'
header = {"User-Agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_5)AppleWebKit 537.36 (KHTML, like Gecko)     Chrome","Accept":"text/html,application/xhtml+xml,application/xml;q=0.9,image/webp    ,*/*;q=0.8"}

user = "username"
pwrd = "password"

response = requests.post(url,headers = header, auth=(user, pwrd))
page = requests.get('https://fahrkarten.bahn.de/privatkunde/meinebahn/meine_bahn_portal.go?lang=de&country=DEU#stay')

soup = BeautifulSoup(page.text, 'html.parser')

不幸的是,这不起作用,因为soup 是一个 html 文本,其中包含“您已退出我们的系统”。虽然response的结果是<Response [200]>

我对@9​​87654328@有点挣扎,原因有两个:

  1. 我对 auth 方法的理解是否正确,即首先发布登录详细信息,然后访问登录“背后”的网站)还是这种方式不同?
  2. 如何确定网站是否需要更特殊的身份验证方法?在 html 代码中是否有要查找的关键字?

任何帮助将不胜感激,因为我真的很想理解它,而且我显然是“新手”从手册中得到正确的结论(例如http://docs.python-requests.org/en/master/user/authentication/

【问题讨论】:

    标签: python beautifulsoup python-requests


    【解决方案1】:

    了解网站身份验证如何工作的最简单方法是在登录时捕获流量,然后找出幕后发生的事情:使用哪个 URL,提交什么数据等

    你可以使用fiddlercharles,或者最方便的Chrome Dev Tools(F12启动),是这样的:

    在你的情况下,整个请求是:

    POST /privatkunde/start/start.post HTTP/1.1
    Host: fahrkarten.bahn.de
    Connection: keep-alive
    Content-Length: 74
    Cache-Control: max-age=0
    Origin: https://www.bahn.de
    Upgrade-Insecure-Requests: 1
    User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.76 Safari/537.36
    Content-Type: application/x-www-form-urlencoded
    Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
    Referer: https://www.bahn.de/p/view/meinebahn/login.shtml
    Accept-Encoding: gzip, deflate, br
    Accept-Language: en-US,en;q=0.8
    
    scope=bahnde&lang=de&country=DEU&username=demo&password=demo&login-submit=
    

    最重要的是,由于 cookie 用于身份验证/验证,因此整个过程都需要一个会话,然后用于访问只有登录用户才能访问的其他网页。

    import requests
    
    session = requests.Session() # create a session that handles cookies by default
    
    headers = {"User-Agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_5)AppleWebKit 537.36 (KHTML, like Gecko)     Chrome"
              ... # simulate headers that is used in the actual POST request
    } 
    
    data = {'scope': 'bahnde', 'lang': 'de', 'country': 'DEU', 
            'username': 'xxxx', 'password': 'xxxx', 'login-submit': ''
           }
    
    # now login
    response = session.post(url='https://fahrkarten.bahn.de/privatkunde/start/start.post', data=data, headers=headers)
    
    # once logged in, session can be used to access other web pages
    # sometimes you also want to make sure it actually logged in by checking content from response.text
    content = response.text 
    # try to look for your username or other flags with content.find etc. 
    r2 = session.get(url='xxx') # access other pages
    

    【讨论】:

    • 谢谢!!有用。我是个新手,有时会卡住,因为我缺乏背景知识。所以谢谢你的解释。这真的有帮助!也许是一个有些愚蠢的问题。我怎么知道这里正在使用 cookie?
    • 嗯,当您使用现代浏览器(例如 Chrome/Firefox)浏览网站时,浏览器会自动处理 cookie。 requests.Session() 提供一个默认处理 cookie 的会话(类似于浏览器的处理方式),并且在任何给定时间,您都可以随时使用 session.cookies 来查看内容。
    • 感谢您的帮助!
    【解决方案2】:

    很可能是你请求了错误的页面,查看登录页面中的表单:

    <form method="post" name="staticLogin" id="kv-static-logi" action="https://fahrkarten.bahn.de/privatkunde/start/start.post">
    <input name="scope" value="bahnde" type="hidden">
    <input name="lang" value="de" type="hidden">
    <input name="country" value="DEU" type="hidden">
    <p>
    <input id="kv-static-login-username_ab" name="username" class="from" maxlength="60" autocomplete="off" placeholder="Benutzername" type="text">
    </p>
    
    <p>
    <input id="kv-static-login-password_ab" name="password" class="from" maxlength="60" placeholder="Passwort" type="password">
    </p>
    
    <p><button type="submit" name="login-submit" class="btn slim no-margin" style="float: left">Login</button>
    <a id="vergessen" href="https://fahrkarten.bahn.de/privatkunde/start/start.post?scope=pwvergessen&amp;lang=de">Login vergessen?</a>
    </p></form>
    

    您应该请求带有usernamepassword 字段的页面https://fahrkarten.bahn.de/privatkunde/start/start.post。保留请求给你的东西! (令牌等...)

    再见!

    【讨论】:

    • 感谢您的快速支持。我已经更改了网址,但不幸的是这无济于事。从您的回答中,我确实认为我的一般方法没有错,但我肯定还缺少其他东西。
    猜你喜欢
    • 1970-01-01
    • 2018-12-02
    • 2014-01-15
    • 1970-01-01
    • 2012-11-29
    • 2020-08-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多