1

私はPythonを学んでおり、最初のプロジェクトとして、いくつかの航空会社のWebサイトにログインして、マイレージ会員のマイル情報をスクレイピングしたいと考えています。アメリカン航空とユナイテッド航空ではログインしてスクレイピングできましたが、デルタ航空、US エアウェイズ、ブリティッシュエアウェイズではできません。

私が使用してきた方法論は、Fiddler2、Chrome、または Firebug からのネットワーク トラフィックを監視することです。現時点では、Wireshark は複雑すぎるようです。

私のスクリプトが American と United のスクレイピングで動作するようにするには、fiddler2 のトラフィックを監視し、FORM DATA と REQUEST HEADER DATA をコピーしてから、python サードパーティ Requests ライブラリを使用してデータにアクセスしました。とてもシンプルです。非常に簡単。他の航空会社のウェブサイトは私に多くの問題を与えています.

ブリティッシュ・エアウェイズについて具体的に話しましょう。以下は、ダミーの BA アカウントにログインしたときに fiddler から取得した FORM DATA と REQUEST HEADER DATA の写真です。私が使用しているテストスクリプトも含まれています。私は2つの異なるバージョンを書きました。1 つは Requests ライブラリを使用し、もう 1 つは urllib を使用します。どちらも同じエラーを生成しますが、Requests ライブラリがインポートされていない場合に誰かが私を助けやすくするために、両方を提供すると思いました。お好きな方をご利用ください。

基本的に、request.post を作成すると、

10054、「既存の接続がリモート ホストによって強制的に閉じられました」エラー。

何が起こっているのかわかりません。3日探しても何も出てこない。誰かが私を助けてくれることを願っています。以下のコードは、ダミーの BA アカウント情報を使用しています。ユーザー名:python_noob パスワード:p4ssword。自由に使用してテストしてください。

ここにfiddler2データの写真があります

http://i.imgur.com/iOL91.jpg?1

http://i.imgur.com/meLHL.jpg?1

import requests

import urllib


def get_BA_login_using_requests ():
    url_loginSubmit1 = 'https://www.britishairways.com/travel/loginr/public/en_us'

    url_viewaccount1 = 'https://www.britishairways.com/travel/viewaccount/public/en_us?eId=106011'
    url_viewaccount2 = 'https://www.britishairways.com/travel/viewaccount/execclub/_gf/en_us?eId=106011'


    form_data = {
        'Directional_Login':'',
        'eId':'109001',
        'password':'p4ssword',
        'membershipNumber':'python_noob',
        }


    request_headers= {
        'Cache-Control':'max-age=0',
        'Accept':'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
        'Accept-Charset':'ISO-8859-1,utf-8;q=0.7,*;q=0.3',
        'Accept-Encoding':'gzip,deflate,sdch',
        'Accept-Language':'en-US,en;q=0.8',
        'User-Agent':'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.11 (KHTML, like Gecko) Chrome/23.0.1271.97 Safari/537.11',

        'Cookie': 'BIGipServerba.com-port80=997762723.20480.0000; v1st=EDAB42A278BE913B; BASessionA=kDtBQWGclJymXtlsTXyYtykDLLsy3KQKvd3wMrbygd7JZZPJfJz2!-1893405604!clx42al01-wl01.baplc.com!7001!-1!-407095676!clx43al01-wl01.baplc.com!7001!-1; BIGipServerba.com-port81=997762723.20736.0000; BA_COUNTRY_CHOICE_COOKIE=us; Allow_BA_Cookies=accepted; BA_COUNTRY_CHOICE_COOKIE=US; opvsreferrer=functional/home/home_us.jsp; realreferrer=; __utma=28787695.2144676753.1356203603.1356203603.1356203603.1; __utmb=28787695.1.10.1356203603; __utmc=28787695; __utmz=28787695.1356203603.1.1.utmcsr=(direct)|utmccn=(direct)|utmcmd=(none); fsr.s={"v":-2,"rid":"d464cf7-82608645-1f31-3926-49807","ru":"http://www.britishairways.com/travel/globalgateway.jsp/global/public/en_","r":"www.britishairways.com","st":"","to":3,"c":"http://www.britishairways.com/travel/home/public/en_us","pv":1,"lc":{"d0":{"v":1,"s":false}},"cd":0}',

        'Content-Length':'78',
        'Content-Type':'application/x-www-form-urlencoded',

        'Origin':'https://www.britishairways.com',
        'Referer':'https://www.britishairways.com/travel/loginr/public/en_us',

        'Connection':'keep-alive',
        'Host':'www.britishairways.com',
        }



    print ('Trying to login to British Airways using Requests Library (takes about 1 minute for error to occur)')


    try:
        r1 = requests.post(url_loginSubmit1, data = form_data, headers = request_headers)
    print ('it worked')
    except Exception as e:
        msg = "An exception of type {0} occured, these were the arguments:\n{1!r}"
        print (msg.format(type(e).__name__, e.args))


    return







def get_BA_login_using_urllib():
    """Tries to request the URL. Returns True if the request was successful; false otherwise.
    https://www.britishairways.com/travel/loginr/public/en_us

    response -- After the function has finished, will possibly contain the response to the request.

    """
    response = None
    print ('Trying to login to British Airways using urllib Library (takes about 1 minute for error to occur)')
    # Create request to URL.
    req = urllib.request.Request("https://www.britishairways.com/travel/loginr/public/en_us")

    # Set request headers.
    req.add_header("Connection", "keep-alive")
    req.add_header("Cache-Control", "max-age=0")
    req.add_header("Origin", "https://www.britishairways.com")
    req.add_header("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.11 (KHTML, like Gecko) Chrome/23.0.1271.97 Safari/537.11")
    req.add_header("Content-Type", "application/x-www-form-urlencoded")
    req.add_header("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8")
    req.add_header("Referer", "https://www.britishairways.com/travel/home/public/en_us")
    req.add_header("Accept-Encoding", "gzip,deflate,sdch")
    req.add_header("Accept-Language", "en-US,en;q=0.8")
    req.add_header("Accept-Charset", "ISO-8859-1,utf-8;q=0.7,*;q=0.3")
    req.add_header("Cookie", 'BIGipServerba.com-port80=997762723.20480.0000; v1st=EDAB42A278BE913B; BIGipServerba.com-port81=997762723.20736.0000; BA_COUNTRY_CHOICE_COOKIE=us; Allow_BA_Cookies=accepted; BA_COUNTRY_CHOICE_COOKIE=US; BAAUTHKEY=BA4760A2434L; BA_ENROLMENT_APPLICATION_COOKIE=1356219482491AT; BASessionA=wKG4QWGSTggNGnsLTnrgQnMxGMyzvspGLCYpjdSZgv2pSgYN1YRn!-1893405604!clx42al01-wl01.baplc.com!7001!-1!-407095676!clx43al01-wl01.baplc.com!7001!-1; HOME_AD_DISPLAY=1; previousCountryInfo=us; opvsreferrer=functional/home/home_us.jsp; realreferrer=; __utma=28787695.2144676753.1356203603.1356216924.1356219076.6; __utmb=28787695.15.10.1356219076; __utmc=28787695; __utmz=28787695.1356203603.1.1.utmcsr=(direct)|utmccn=(direct)|utmcmd=(none); fsr.s={"v":-2,"rid":"d464cf7-82608645-1f31-3926-49807","ru":"http://www.britishairways.com/travel/globalgateway.jsp/global/public/en_","r":"www.britishairways.com","st":"","to":5,"c":"https://www.britishairways.com/travel/home/public/en_us","pv":31,"lc":{"d0":{"v":31,"s":true}},"cd":0,"f":1356219889982,"sd":0}')

    # Set request body.
    body = b"Directional_Login=&eId=109001&password=p4ssword&membershipNumber=python_noob"

    # Get response to request.


    try:
        response = urllib.request.urlopen(req, body)
        print ('it worked')
    except Exception as e:
        msg = "An exception of type {0} occured, these were the arguments:\n{1!r}"
        print (msg.format(type(e).__name__, e.args))

    return



def main():
    get_BA_login_using_urllib()
    print()
    get_BA_login_using_requests()
    return


main()
4

2 に答える 2

1

率直に言えば、不正または違法なリクエストの作成に成功し、反対側のサーバー (またはプロキシ) が単にそれを処理することを拒否したと言えます。

  1. requests図書館を利用してください。素晴らしいです。Urllib はかなり時代遅れです (そして、まあ、まったく楽しくありません)。

  2. ほぼすべてのカスタム ヘッダーを取り除きます。特にContent-Length、、、および。Keep-Alive_ 最初の 3 つは、HTTP 1.1 プロトコルの一部であるため、要求ライブラリに処理させる必要があります。:に関しても、セッションの使用方法に応じて、ライブラリによって処理されます。以前の Cookie がないと、サイトにアクセスしようとすると 401 のようなメッセージが表示されるか、(透過的に) ログイン ページにリダイレクトされます。ログインを行うと、正しい Cookie が設定されます。その後、元のリクエストを再試行できるはずです。ConnectionCookieCookierequests

  3. ポストデータに dict を使用する場合、Content-Typeヘッダーも必要ありません。上記の辞書でユニコード値を使用して実験することをお勧めします。それが時々違いを生むことがわかりました。

つまり、できる限り削除してから、そこから構築してください。通常、このようなことを行うのに数行以上かかることはありません。さて、Web ページをスクレイピングすることは別の問題です。それには「beautifulsoup」を試してください。

PS: 公開フォーラムに Cookie データを投稿しないでください。個人情報やその他の機密データが含まれている可能性があり、怪しげなキャラクターが悪用される可能性があります

于 2012-12-23T12:21:33.713 に答える
0

私の問題の原因である Python 3.3 の Windows バージョンにバグがあるようです。ここからの回答を使用しました

HTTPS 要求により、Python 3 を使用する Windows で接続がリセットされる

私のスクリプトのurllibバージョンを進めるために。リクエストを使用したいので、そのモジュールで SSL ダウングレードを回避する方法を理解する必要があります。それは別スレにします。誰かがそれに対する答えを持っている場合は、ここにも投稿できます。どうも。

于 2012-12-23T21:17:40.863 に答える