2016-12-28 11 views
1

大気中の粒子状物質の値をテーブルから取得したい(悲しいことに、サイトは英語ではないので、すべてを尋ねてください):BeautifulSoupとGET requestsで送信されたリクエストは、テーブルがブートストラップでディナミックに満たされており、BeautifulSoupのようなパーサーはまだ挿入する必要がある値を見つけることができません。POST要求は常に「許可されていないキー文字」を返す

Firebugを使用して、私はページのあらゆる角度をチェックしました。テーブルの別の日を選択すると、POST要求が送信されました(Refererのようなサイトはhttp://www.arpat.toscana.it/temi-ambientali/aria/qualita-aria/bollettini/index/regionale/です。 )である:以下のparamsで

POST /temi-ambientali/aria/qualita-aria/bollettini/aj_dati_bollettini HTTP/1.1 
Host: www.arpat.toscana.it  
User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:50.0) Gecko/20100101 Firefox/50.0 
Accept: */*  
Accept-Language: en-US,en;q=0.5 
Accept-Encoding: gzip, deflate 
Content-Type: application/x-www-form-urlencoded; charset=UTF-8 
X-Requested-With: XMLHttpRequest 
Referer: http://www.arpat.toscana.it/temi-ambientali/aria/qualita-aria/bollettini/index/regionale/26-12-2016 
Content-Length: 114 
Cookie: [...] 
DNT: 1 
Connection: keep-alive 

:答えで

v_data_osservazione=26-12-2016&v_tipo_bollettino=regionale&v_zona=&csrf_test_name=b88d2517c59809a529 
b6f8141256e6ca 

データはJSON形式です。

私はテーブルを埋めるJSONデータを直接取得するために、自分のPOSTリクエストを作成し始めました。

日付に加えて、csrf_test_nameが必要です。このサイトはCSRF vulnerabilityに対して保護されています。 paramsで正しいクエリを実行するには、私はCSRFトークンが必要です。そのため、サイトへのGETリクエスト(URLのPOSTリクエストでRefererを参照)を実行し、次のようにCSRFトークンを取得します:

r = get(url) 
csrf_token = r.cookies["csrf_cookie_name"] 

私のCSRFトークンとPOSTリクエストを準備して、私はそれを送信し、ステータスコード200で、私はいつもDisallowed Key Characters.になります!

このエラーを探していると、私はいつも私が必要としているCodeIgniterに関する記事を見ています。ヘッダーとパラメータのすべての組み合わせを試しましたが、何も変わりませんでした。 BeautifulSouprequestsをあきらめて、Seleniumの学習を開始する前に、Seleniumが高すぎると、低レベルのライブラリBeautifulSouprequestsのようなものが私には役に立つことがたくさんあるので、私は好きですこれら2つの学習を続けます。

ここでは、コードです:

from requests import get, post 
from bs4 import BeautifulSoup 
import datetime 
import json 

url = "http://www.arpat.toscana.it/temi-ambientali/aria/qualita-aria/bollettini/index/regionale/" # + %d-%m-%Y 
yesterday = datetime.date.today() - datetime.timedelta(1) 
date_object = datetime.datetime.strptime(str(yesterday), '%Y-%m-%d') 
yesterday_string = str(date_object.strftime('%d-%m-%Y')) 

full_url = url + yesterday_string 
print("REFERER " + full_url) 

r = get(url) 
csrf_token = r.cookies["csrf_cookie_name"] 
print(csrf_token) 

# preparing headers for POST request 
headers = { 
    "Host": "www.arpat.toscana.it", 
    "Accept" : "*/*", 
    "Accept-Language" : "en-US,en;q=0.5", 
    "Accept-Encoding" : "gzip, deflate", 
    "Content-Type" : "application/x-www-form-urlencoded; charset=UTF-8", 
    "X-Requested-With" : "XMLHttpRequest", # XHR 
    "Referer" : full_url, 
    "DNT" : "1", 
    "Connection" : "keep-alive" 
} 

# preparing POST parameters (to be inserted in request's body) 
payload_string = "v_data_osservazione="+yesterday_string+"&v_tipo_bollettino=regionale&v_zona=&csrf_test_name="+csrf_token 
print(payload_string) 

# data -- (optional) Dictionary, bytes, or file-like object to send in the body of the Request. 

# json -- (optional) json data to send in the body of the Request. 
req = post("http://www.arpat.toscana.it/temi-ambientali/aria/qualita-aria/bollettini/aj_dati_bollettini", 
    headers = headers, json = payload_string 
) 

print("URL " + req.url) 

print("RESPONSE:") 
print('\t'+str(req.status_code)) 
print("\tContent-Encoding: " + req.headers["Content-Encoding"]) 
print("\tContent-type: " + req.headers["Content-type"]) 
print("\tContent-Length: " + req.headers["Content-Length"]) 
print('\t'+req.text) 
+0

あなたは維持したい場合学習し、あなたのために必要なリクエストを使用するクッキー、参照、ヘッダー管理の助けを借りて、私は['scrapy'](https://scrapy.org)をチェックすることをお勧めします – eLRuLL

+0

私のコードで何が悪いのかを知りたいのですが、' scrapy '試しにふさわしいかもしれない。あなたの提案に感謝しています。 – elmazzun

+0

あなたはhttp://httpbin.orgを使って 'POST'を送ることができ、受信したすべてのデータを送り返すことができます。そして、それをブラウザとサーバとの間のデータと比較することができます。要求の違いを見つけることができます。 – furas

答えて

1

このコードは、私の作品:

  • 私はrequest.Session()を使用して、それは私がdata=代わりのjson=
  • 最終的に私ドンを使用
  • すべてのクッキーを保持しますが、すべてのコメントの要素が必要です
  • ブラウザの要求とコード要求を比較するために、私はCharlesウェブデバッグプロキシアプリケーションを使用

コード:

import requests 
import datetime 

#proxies = { 
# 'http': 'http://localhost:8888', 
# 'https': 'http://localhost:8888', 
#} 

s = requests.Session() 
#s.proxies = proxies # for test only 

date = datetime.datetime.today() - datetime.timedelta(days=1) 
date = date.strftime('%d-%m-%Y') 

# --- main page --- 

url = "http://www.arpat.toscana.it/temi-ambientali/aria/qualita-aria/bollettini/index/regionale/" 

print("REFERER:", url+date) 

r = s.get(url) 

# --- data --- 

csrf_token = s.cookies["csrf_cookie_name"] 

#headers = { 
    #'User-Agent': 'User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:50.0) Gecko/20100101 Firefox/50.0', 
    #"Host": "www.arpat.toscana.it", 
    #"Accept" : "*/*", 
    #"Accept-Language" : "en-US,en;q=0.5", 
    #"Accept-Encoding" : "gzip, deflate", 
    #"Content-Type" : "application/x-www-form-urlencoded; charset=UTF-8", 
    #"X-Requested-With" : "XMLHttpRequest", # XHR 
    #"Referer" : url, 
    #"DNT" : "1", 
    #"Connection" : "keep-alive" 
#} 

payload = { 
    'csrf_test_name': csrf_token, 
    'v_data_osservazione': date, 
    'v_tipo_bollettino': 'regionale', 
    'v_zona': None, 
} 

url = "http://www.arpat.toscana.it/temi-ambientali/aria/qualita-aria/bollettini/aj_dati_bollettini" 
r = s.post(url, data=payload) #, headers=headers) 

print('Status:', r.status_code) 
print(r.json()) 

プロキシ:

enter image description here

enter image description here

+0

本当にありがとうございます! 'Session'と' Charles'が離れていると、POSTリクエストにparamsを間違った方法で渡していたようです。 – elmazzun

+0

それは日付の問題です - まだ '28-12-2016'の情報はありません。 – furas

+0

あなたは正しいです、データがまだロードされていることを認識した後にコメントを削除しました。コメントを削除しました:それは午前2時でした。私はかなり疲れていました。またか – elmazzun

関連する問題