2016-10-08 12 views
2

Philly Police webpageの所与の場所から警察区を取得しようとしています。手でこれを行うにはあまりにも多くの場所があるので、私はPythonのリクエストライブラリを使ってプロセスを自動化しようとしています。 Webページの以下のように位置の値を保持している形式は次のとおりです。Python3は、投稿要求を許可しないフォームを提出するようにライブラリを要求します。

<form id="search-form" method="post" action="districts/searchAddress"> 
<fieldset> 
    <div class="clearfix"> 
     <label for="search-address-box"><span>Enter Your Street Address</span></label> 
     <div class="input"> 
      <input tabindex="1" class="district-street-address-input" id="search-address-box" name="name" type="text" value=""> 
     </div> 
    </div> 
    <div class="actions" style="float: left;"> 
     <button tabindex="3" type="submit" class="btn btn-success">Search</button> 
    </div> 
    <a id="use-location" href="https://www.phillypolice.com/districts/index.html?_ID=7&_ClassName=DistrictsHomePage#" style="float: left; margin: 7px 0 0 12px;"><i class="icon-location-arrow"></i>Use Current Location</a> 
    <div id="current-location-display" style="display: none;"><p>Where I am right now.</p></div> 
</fieldset> 
</form> 

しかし、私は、以下のものを使用して投稿したり、ウェブページに置くしようとすると:

r = requests.post('http://www.phillypolice.com/districts',data={'search-address-box':'425 E. Roosevelt Blvd'}) 

私はエラー405を取得するには、POSTが許可されていません。私はJavascriptをオフにしてウェブページ上でその区域を見つけようとしました。私が提出したときに同じ405のエラーメッセージを受け取りました。したがって、フォームは間違いなく提出されず、地区はJavaScriptを使用して検索されます。

リクエストライブラリを使用してJavaScriptをトリガーする送信ボタンを 'クリック'する方法はありますか?あなたは「提出」打ったとき

答えて

2

データが最初の最後のリクエストは、次のように取得された座標にGoogleマップを照会した後に取得されます。bing maps apiとセットアップ無料アカウントをすることができます

enter image description here

とCOORDSを取得我々はそれマイナス私のキーを実行する場合

import requests 

key = "my_key" 
coord_params = {"output": "json", 
       "key": key} 

# This provides the coordinates. 
coords_url = "https://dev.virtualearth.net/REST/v1/Locations" 

# Template to pass each address to in your actual loop. 
template = "{add},US" 
url = "https://api.phillypolice.com/jsonservice/Map/searchAddress.json" 
with requests.Session() as s: 
    # Add the query param passing in each zipcode 
    coord_params["query"] = template.format(add="425 E. Roosevelt Blvd") 
    js = s.get(coords_url, params=coord_params).json() 
    # Parse latitude and longitude from the returned json. 
    # Call str to make make it into `(lat, lon)` 
    latitude_longitude = str((js[u'resourceSets'][0][u'resources'][0]["point"][u'coordinates'])) 
    data = s.get(url, params={"latlng": latitude_longitude}) 

    print(data.json()) 

:あなたは、GETリクエストを行う必要があり

In [2]: import requests 
    ...: 
    ...: key = "my_key..." 
    ...: 
    ...: coord_params = {"output": "json", 
    ...:     "key": key} 
    ...: coords_url = "https://dev.virtualearth.net/REST/v1/Locations" 
    ...: template = "{add},US" 
    ...: url = "https://api.phillypolice.com/jsonservice/Map/searchAddress.json" 
    ...: with requests.Session() as s: 
    ...:  coord_params["query"] = template.format(add="425 E. Roosevelt Blvd") 
    ...: 
    ...:  js = s.get(coords_url, params=coord_params).json() 
    ...:  latitude_longitude = str(js[u'resourceSets'][0][u'resources'][0]["po 
    ...: int"][u'coordinates']) 
    ...:  print(latitude_longitude) 
    ...:  data = s.get(url, params={"latlng": latitude_longitude}) 
    ...:  print(data.json()) 
    ...:  
[40.02735900878906, -75.1153564453125] 
{'response': ['35', '2', 'Marques Newsome', '[email protected] ', '267-357-1436']} 

ブラウザでリクエストを見たときに表示されるレスポンスと一致することがわかります。

+1

いいえ、Google geocode apiを使用しないのは公正ではありません!良いアイデア! – alecxe

+1

@alecxe、私は何と言うことができます、私は無料のものが好きです! –

1

が起こって2つの主要なものがあります - Googleのジオコードサービスとジオコードサービスによって返された座標を使用しています「searchAddress.json」エンドポイントへのXHRリクエストへの要求があります。

上記の要求をすべてのAPIキーと必要なパラメータを注意深く処理するようにシミュレートするか、より高いレベルにとどまり、でブラウザの自動化を使用できます。

PhantomJS headless browserを使用しての作業例:

In [2]: from selenium import webdriver 

In [3]: driver = webdriver.PhantomJS() 

In [4]: driver.get("https://www.phillypolice.com/districts/") 

In [5]: address = "425 E. Roosevelt Blvd" 

In [6]: search_box = driver.find_element_by_id("search-address-box") 

In [7]: search_box.send_keys(address) 

In [8]: search_box.submit() 

In [9]: driver.find_element_by_css_selector("#district-menu h2").text 
Out[9]: u'35th District' 

In [10]: driver.find_element_by_css_selector("#district-menu h4").text 
Out[10]: u'PSA 2' 

そして、あなたは "タイミング" の問題を処理するためにExplicit Waitsが必要になる場合があります。

+0

答えがセレンを使用しているので、この例はありがたいことですが、要求がジョブにとって最適なツールではないと考えるのは安全でしょうか? – Turtle

+0

@Turtleも、あなたは依然としてGoogleへのリクエストとphllypoliceへのリクエストの両方を '要求 'で行うことができます。これは単なる低レベルのもので、より多くの動く部品が必要になります。私はあなたにそのオプションをも提供できるかどうかを見ていきます。ありがとう。 – alecxe

+0

これは実際には機能しません。私はセレンの例外が見つかりませんでした。私はちょうど関数内でこのコードを使用してアドレスを反復しようとしました。ドライバを毎回リセットする必要がありますか? – Turtle

関連する問題