Python-web-scraping-dynamic-websites

提供:Dev Guides
移動先:案内検索

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()