Pythonのリクエストモジュールを使用してWebサイトに「ログイン」する方法


95

Pythonのリクエストモジュールを使用してWebサイトにログインするリクエストを投稿しようとしていますが、実際には機能しません。私はこれに慣れていないので、自分のユーザー名とパスワードのCookieを作成する必要があるのか​​、または特定の種類のHTTP承認を作成する必要があるのか​​わかりません(??)。

from pyquery import PyQuery
import requests

url = 'http://www.locationary.com/home/index2.jsp'

だから今、私は「投稿」とクッキーを使うことになっていると思います...

ck = {'inUserName': 'USERNAME/EMAIL', 'inUserPass': 'PASSWORD'}

r = requests.post(url, cookies=ck)

content = r.text

q = PyQuery(content)

title = q("title").text()

print title

クッキーを間違えているような気がします...わかりません。

正しくログインできない場合は、ホームページのタイトルが「Locationary.com」に表示され、表示される場合は「ホームページ」になります。

リクエストとCookieについていくつか説明していただければ助かります。:D

ありがとう。

...まだ実際には機能していません。さて...ログインする前のHTMLのホームページの内容は次のとおりです。

</td><td><img src="http://www.locationary.com/img/LocationaryImgs/icons/txt_email.gif">    </td>
<td><input class="Data_Entry_Field_Login" type="text" name="inUserName" id="inUserName"  size="25"></td>
<td><img src="http://www.locationary.com/img/LocationaryImgs/icons/txt_password.gif"> </td>
<td><input  class="Data_Entry_Field_Login"  type="password" name="inUserPass"     id="inUserPass"></td>

だから私はそれを正しくやっていると思いますが、出力はまだ「Locationary.com」です

2番目の編集:

長い間ログインしたままにしたいのですが、そのドメインでページをリクエストするときはいつでも、ログインしたかのようにコンテンツを表示します。

回答:


44

必要な情報がページにある場合は、ログイン後すぐにリダイレクトされます...

代わりに、python-requestsドキュメントのように、ck変数payloadを呼び出してみましょう:

payload = {'inUserName': 'USERNAME/EMAIL', 'inUserPass': 'PASSWORD'}
url = 'http://www.locationary.com/home/index2.jsp'
requests.post(url, data=payload)

さもないと...

下記のhttps://stackoverflow.com/a/17633072/111362を参照してください


urllib、urrlib2、cookielib、およびいくつかのHTTPヘッダーを使用して別の方法で機能させることができました。
マーカスジョンソン

23
残念ながら、これは受け入れられた回答なので削除できません。これを投稿したときは質問が理解できなかったと思います(後で明確になりました)が、なぜ受け入れられたのかわかりません。私の答えは、必要なデータがログイン後にリダイレクトされるページにある場合にのみ機能します。@tigerFinchの方がはるかに優れています。
katy lavallee 2015年

227

私はあなたが別の解決策を見つけたのを知っていますが、この質問を見つけた私のような人々が同じことを探している場合、それは次のような要求で達成できます:

まず、Marcusが行ったように、ログインフォームのソースを確認して、フォームの投稿先のURL、およびユーザー名とパスワードのフィールドの名前属性の3つの情報を取得します。彼の例では、それらはinUserNameとinUserPassです。

これを取得したら、requests.Session()インスタンスを使用して、ログインの詳細をペイロードとして含むログインURLへの投稿リクエストを作成できます。セッションインスタンスからのリクエストは、通常のリクエストの使用と基本的に同じです。永続性を追加するだけで、Cookieなどを保存して使用できます。

ログインが成功したと仮定すると、単にセッションインスタンスを使用して、サイトにさらにリクエストを送信できます。あなたを識別するCookieは、リクエストを承認するために使用されます。

import requests

# Fill in your details here to be posted to the login form.
payload = {
    'inUserName': 'username',
    'inUserPass': 'password'
}

# Use 'with' to ensure the session context is closed after use.
with requests.Session() as s:
    p = s.post('LOGIN_URL', data=payload)
    # print the html returned or something more intelligent to see if it's a successful login page.
    print p.text

    # An authorised request.
    r = s.get('A protected web page url')
    print r.text
        # etc...

12
問題は、POSTログインフォームを取得する方法です。ユーザー名、ユーザー名などではなく、inUserNameと呼ばれているかどうかを確認するにはどうすればよいですか?
lsheng 14

4
@TwinkleはフォームのHTMLソースを調べて、フォームの名前を確認します。
アーロンシューマッハ

3
s.textは機能していないようですが、リクエストでこの素敵なものを表示することについて投票の愛情を与えています...構文
ソフトウェアの預言​​者

s.textは次のようになるため機能しません。p = s.post('LOGIN_URL.....それからp.text
Sebastian

2
@HalcyonAbrahamRamirez私はあなたが助けを求めるのにこれが正しい場所だとは思いません。stackoverflow.com/questions/21928368/…のような具体的な課題についての質問を読んで、解決できない場合は独自の質問を開いてください。
セバスチャン

36

簡単にするために、サイトのURLがhttp://example.com/で、ユーザー名とパスワードを入力してサインアップする必要があるとしましょうログインページにアクセスして、http:// exampleと入力します今すぐcom / login.phpを実行してソースコードを表示し、フォームタグに含まれるアクションURLを検索します。

 <form name="loginform" method="post" action="userinfo.php">

userinfo.phpを取得して ' http://example.com/userinfo.php 'になる絶対URLを作成し、単純なpythonスクリプトを実行します。

import requests
url = 'http://example.com/userinfo.php'
values = {'username': 'user',
          'password': 'pass'}

r = requests.post(url, data=values)
print r.content

これがいつか誰かを助けることを願っています。


1
良いもの-名前/パスフィールドの要素を検査すると、ボタンではなく呼び出されたファイルが表示される場合があることに注意してください(ボタン検査で「アクション」と言っただけで、URLはusr /パスフィールドの検査から表示されました)
baxx

2
Chromeを使用している場合は、ネットワークタブでdevtoolsを開き、リクエストを行った後、実際の値を、どのキーとどこに送信されたかを調べることができます。これは、従来のメカニズムを使用しないフォームや、代わりにjavascript / ajaxを使用してフォームを処理します。
Roberto Arosemena

1
この場合、ページのコンテンツを印刷するのではなく、Webページを直接ポップアップさせる方法に関するアイデアはありますか?

webbrowserモジュールを使用する必要があります
R.バレット

また、彼の上記print r.contentは間違っているため、使用する必要があるprint(r.content)
R.バレット

6

ユーザー名<...name=username.../>とパスワードのWebサイトフォームで使用されている入力の名前を確認<...name=password../>し、以下のスクリプトで置き換えます。また、ログインする目的のサイトを指すようにURLを置き換えます。

login.py

#!/usr/bin/env python

import requests
from requests.packages.urllib3.exceptions import InsecureRequestWarning
requests.packages.urllib3.disable_warnings(InsecureRequestWarning)
payload = { 'username': 'user@email.com', 'password': 'blahblahsecretpassw0rd' }
url = 'https://website.com/login.html'
requests.post(url, data=payload, verify=False)

を使用するとdisable_warnings(InsecureRequestWarning)、検証されていないSSL証明書を使用してサイトにログインしようとしたときに、スクリプトからの出力がすべて沈黙します。

追加:

このスクリプトをUNIXベースのシステムのコマンドラインから実行するには、スクリプトをhome/scriptsディレクトリに配置します。つまり、このディレクトリをパス~/.bash_profileまたはターミナルで使用される同様のファイルに追加します。

# Custom scripts
export CUSTOM_SCRIPTS=home/scripts
export PATH=$CUSTOM_SCRIPTS:$PATH

次に、このpythonスクリプトへのリンクを作成します home/scripts/login.py

ln -s ~/home/scripts/login.py ~/home/scripts/login

端末を閉じて、新しい端末を起動し、実行します login


4

このrequests.Session()ソリューションは、CSRF保護を備えたフォームへのログインを支援しました(Flask-WTFフォームで使用されます)。csrf_token非表示フィールドとしてa が必要かどうかを確認し、ユーザー名とパスワードを使用してペイロードに追加します。

import requests
from bs4 import BeautifulSoup

payload = {
    'email': 'email@example.com',
    'password': 'passw0rd'
}     

with requests.Session() as sess:
    res = sess.get(server_name + '/signin')
    signin = BeautifulSoup(res._content, 'html.parser')
    payload['csrf_token'] = signin.find('input', id='csrf_token')['value']
    res = sess.post(server_name + '/auth/login', data=payload)
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.