requests ライブラリが Web サイトにログインします。Session() と session() の違いは非常にひどいです

著者は最近 Python を使用して Web サイトをクロールし、ホームページではユーザー名とパスワードを入力する必要がありますが、Web サイトでは確認コードが必要ないため、ログイン手順は比較的簡単です。Selenium の webdriver を使用して Chrome ブラウザーを開き、ログインを自動化します。コードは難しくなく、ログインは非常にスムーズです。後で考えてみると、selenium はブラウザーを開くのが遅く、メモリを大量に消費します. クロールしたい Web サイトは、認証コードなどの面倒な検証を必要としないため、要求ライブラリーを使用して Web サイトにログインするだけでよいでしょうか? ?

最初にウェブサイトのホームページのソースコードを分析し、ウェブサイトにログインするために投稿アクションが必要であること、およびユーザー名、パスワードなどのいくつかのフォームデータが必要であること、およびハッシュ値も必要であることを理解します。このハッシュ値はウェブページが更新されるたびに異なるため、ウェブページのソースコードでは re ライブラリの re.search() を使用して取得します。次に、urlencode() を使用してログイン用のフォーム データを url にコンパイルし、投稿します。

import requests
from urllib.parse import urlencode

headers={'user-agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/105.0.0.0 Safari/537.36'}

res=requests.get('https://。。。。。。.com',headers=headers)
if res.status_code==200:
    res=res.text
else:
    print('打开网页失败。')
    exit()

# 查找网页源代码中的hash值
try:
    hash_value=re.search('name="hash" value="(.*?)"',res)[1]
except Exception:
    print('找不到hash值')
    exit()

# 登录用的表单数据
data={'username':'这里填你的用户名',
      'password':'你的密码',
      'hash': hash_value,
      }

# 用urlencode把登录表单数据编译成url
posturl='https://。。。。。。.com/login?'+urlencode(data)

res=requests.post(posturl,headers=headers,timeout=10)

if res.status_code!=200:
    print(f'登录失败!错误代码:{str(res.status_code)}')
else:
    print(res.text)

ログインしようとすると失敗し続けます。その後、他の Web サイトで次の解決策を見つけました。

リクエストでは、get() や post() などのメソッドを直接使用すると、Web ページのインターフェイス リクエストをシミュレートできますが、各リクエストが開始されると終了し、Cookie などの関連する認証情報を保存しません。トークン; たとえば、最初に post() リクエストで Web サイトにログインし、2 回目のログインに成功した後にユーザーの個人情報を取得したい場合、再度 post() リクエストを開始すると、最初にログインする必要があります.明らかに、最初にリクエストするときにすでにログインしているのに、2回目に最初にログインするように求められるのはなぜですか? 実際、2 つのリクエストは 2 つのブラウザを使用してアクセスするのと同じであり、2 つのセッションはまったく無関係であるため、2 番目のリクエストではユーザー情報を取得できません。リクエスト内の session() オブジェクトを使用すると、HTTP リクエスト間で特定のパラメーターを維持できます。つまり、同じセッション オブジェクトによって送信されたリクエスト ヘッダーに指定したパラメーターを持たせることができます。もちろん、最も一般的なアプリケーションは、一連の後続のリクエストで Cookie を保持できることです。

つまり、requests.get や post を使うたびに、別のブラウザでリンクを開くのと同じで、同じブラウザで別のリンクを開いたままにしておくには、セッションを使用する必要があります。

そこで、上記のコードのリクエストを次のように変更しました。

import requests
from urllib.parse import urlencode

headers={'user-agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/105.0.0.0 Safari/537.36'}

# 使用session
se=requests.session()

res=se.get('https://。。。。。。.com',headers=headers)
if res.status_code==200:
    res=res.text
else:
    print('打开网页失败。')
    exit()

# 查找网页源代码中的hash值
try:
    hash_value=re.search('name="hash" value="(.*?)"',res)[1]
except Exception:
    print('找不到hash值')
    exit()

# 登录用的表单数据
data={'username':'这里填你的用户名',
      'password':'你的密码',
      'hash': hash_value,
      }

# 用urlencode把登录表单数据编译成url
posturl='https://。。。。。。.com/login?'+urlencode(data)

res=se.post(posturl,headers=headers,timeout=10)

if res.status_code!=200:
    print(f'登录失败!错误代码:{str(res.status_code)}')
else:
    print(res.text)

また失敗!でもチュートリアルに書いてある通りですが、ウェブサイトにJSコードインターセプトの設定はありますか?

次に、他のチュートリアルを参照し、コードをデバッグに変更します.予期せず、元のエラーはセッションの記述方法にあります:

間違った書き方: se = requests.session()

正しい書き方:se = requests.Session()

Session() の先頭の S は大文字にする必要があります。これは、多くの人が始めたときに犯す低レベルの間違いです。小文字の単語はコードを渡すことができますが、実質的な役割を果たさず、ログインが失敗する原因にもならないため、これは Session() として記述する必要があることに注意してください。

おすすめ

転載: blog.csdn.net/Scott0902/article/details/128899017