2017-01-31 220 views
1

我想使用BeautifulSoup來抓取網站。該網站需要登錄。Python ::請求身份驗證

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]>

我與auth有點掙扎,原因有二:

  1. 是我的身份驗證方法的理解甚至是正確的,即首先發送的登錄信息,然後得到一個訪問網站是「後面」的登錄)還是這樣工作不同?
  2. 如何找出網站是否需要更特殊的驗證方法?是否有關鍵字在html代碼中查找?

任何幫助,將不勝感激,因爲我真的想了解它,我顯然是「新手」,從手冊中得到正確的結論(如http://docs.python-requests.org/en/master/user/authentication/

回答

2

弄清楚認證是如何工作的一個網站的最簡單方法是捕獲的流量,同時在記錄,並找出幕後發生了什麼:該網址時,哪些數據被提交等

你可以使用fiddlercharles,或最方便的Chrome瀏覽器開發工具(F12啓動),是這樣的:

login request

而在你的情況下,整體要求是:

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 
+0

謝謝!有用。我是一個新手,有時會卡住,因爲我缺乏背景知識。所以謝謝你的解釋。這真的有幫助!也許有些愚蠢的問題。我怎麼知道這裏使用了cookies? – FredMaster

+0

那麼,當您使用Chrome/Firefox等現代瀏覽器瀏覽網站時,瀏覽器會自動處理Cookie。 'requests.Session()'提供了一個默認處理cookies的會話(與瀏覽器相似),並且在任何時候都可以使用'session.cookies'來檢出內容。 – Shane

+0

感謝您的幫助! – FredMaster

0

,因爲您請求的錯誤很可能頁面,看看形式登錄頁面:

<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 fields請求https://fahrkarten.bahn.de/privatkunde/start/start.post的頁面。保持請求給你的東西! (代幣等)

看到你!

+0

Thx爲您的迅速支持。我改變了網址,但這不利於我。從你的回答中我可以看出,我的一般方法並沒有錯,但是我一定還有其他的東西丟失了。 – FredMaster