Python-web-scraping-dynamic-websites
Python Webスクレイピング-動的Webサイト
この章では、動的なWebサイトでWebスクレイピングを実行する方法と、詳細に関連する概念について学習します。
前書き
Webスクレイピングは複雑なタスクであり、Webサイトが動的な場合は複雑さが増します。 国連のWebアクセシビリティのグローバル監査によると、Webサイトの70%以上が本質的に動的であり、機能をJavaScriptに依存しています。
動的なWebサイトの例
動的なWebサイトの例を見て、なぜスクレイピングが難しいのかを知りましょう。 ここでは、http://example.webscraping.com/places/default/search [[[1]] 上記のWebページからデータをスクレイプしようとする次のPythonスクリプトの出力から判断できます-
import re
import urllib.request
response = urllib.request.urlopen('http://example.webscraping.com/places/default/search')
html = response.read()
text = html.decode()
re.findall('(.*?)
'、テキスト)
出力
[ ]
上記の出力は、スクレイパーの例では、検索しようとしている<div>要素が空であるため、情報の抽出に失敗したことを示しています。
動的なWebサイトからデータをスクレイピングするためのアプローチ
データがJavaScriptで動的にロードされるため、スクレイパーが動的なWebサイトから情報をスクレイピングできないことがわかりました。 そのような場合、動的なJavaScript依存Webサイトからデータをスクレイピングするために、次の2つの手法を使用できます-
- JavaScriptのリバースエンジニアリング
- JavaScriptのレンダリング
JavaScriptのリバースエンジニアリング
リバースエンジニアリングと呼ばれるプロセスは有用であり、Webページによってデータが動的にロードされる方法を理解できます。
これを行うには、指定されたURLの inspect element タブをクリックする必要があります。 次に、 NETWORK タブをクリックして、*。ajax *のパスを持つsearch.jsonを含む、そのWebページに対して行われたすべてのリクエストを検索します。 ブラウザやネットワークタブからAJAXデータにアクセスする代わりに、次のPythonスクリプトの助けを借りてそれを行うことができます-
import requests
url=requests.get('http://example.webscraping.com/ajax/search.json?page=0&page_size=10&search_term=a')
url.json()
例
上記のスクリプトにより、Python jsonメソッドを使用してJSONレスポンスにアクセスできます。 同様に、生の文字列応答をダウンロードし、pythonのjson.loadsメソッドを使用して、それもロードできます。 これは、次のPythonスクリプトの助けを借りて行っています。 基本的に、アルファベット「a」の文字を検索し、JSON応答の結果ページを反復処理することで、すべての国をスクレイピングします。
import requests
import string
PAGE_SIZE = 15
url = 'http://example.webscraping.com/ajax/' + 'search.json?page={}&page_size={}&search_term=a'
countries = set()
for letter in string.ascii_lowercase:
print('Searching with %s' % letter)
page = 0
while True:
response = requests.get(url.format(page, PAGE_SIZE, letter))
data = response.json()
print('adding %d records from the page %d' %(len(data.get('records')),page))
for record in data.get('records'):countries.add(record['country'])
page += 1
if page >= data['num_pages']:
break
with open('countries.txt', 'w') as countries_file:
countries_file.write('n'.join(sorted(countries)))
上記のスクリプトを実行した後、次の出力が得られ、レコードはcountrys.txtという名前のファイルに保存されます。
出力
Searching with a
adding 15 records from the page 0
adding 15 records from the page 1
...
JavaScriptのレンダリング
前のセクションでは、WebページでAPIがどのように機能し、それを使用して単一のリクエストで結果を取得する方法をリバースエンジニアリングしました。 ただし、リバースエンジニアリングを行いながら、次のような困難に直面する可能性があります-
- ウェブサイトは非常に難しい場合があります。 たとえば、ウェブサイトがGoogle Web Toolkit(GWT)などの高度なブラウザツールで作成されている場合、結果のJSコードは機械生成され、理解およびリバースエンジニアリングが困難になります。
- React.js のような一部の高レベルのフレームワークは、すでに複雑なJavaScriptロジックを抽象化することにより、リバースエンジニアリングを困難にします。
上記の問題の解決策は、HTMLを解析し、CSSフォーマットを適用し、JavaScriptを実行してWebページを表示するブラウザレンダリングエンジンを使用することです。
例
この例では、Java Scriptをレンダリングするために、使い慣れたPythonモジュールSeleniumを使用します。 次のPythonコードは、Seleniumを使用してWebページをレンダリングします-
まず、次のようにセレンからウェブドライバーをインポートする必要があります-
from selenium import webdriver
次に、要件に従ってダウンロードしたWebドライバーのパスを指定します-
path = r'C:\\Users\\gaurav\\Desktop\\Chromedriver'
driver = webdriver.Chrome(executable_path = path)
次に、Pythonスクリプトで制御されるWebブラウザーで開きたいURLを指定します。
driver.get('http://example.webscraping.com/search')
これで、選択する要素を設定するために検索ツールボックスのIDを使用できます。
driver.find_element_by_id('search_term').send_keys('.')
次に、次のように選択ボックスの内容を設定するためにJavaスクリプトを使用することができます-
js = "document.getElementById('page_size').options[1].text = '100';"
driver.execute_script(js)
次のコード行は、Webページで検索をクリックする準備ができていることを示しています-
driver.find_element_by_id('search').click()
次のコード行は、AJAXリクエストが完了するまで45秒間待機することを示しています。
driver.implicitly_wait(45)
今、国のリンクを選択するには、次のようにCSSセレクターを使用することができます-
links = driver.find_elements_by_css_selector('#results a')
これで、国のリストを作成するために各リンクのテキストを抽出できます-
countries = [link.text for link in links]
print(countries)
driver.close()