Python Web Kazıma - Dinamik Web Siteleri

Bu bölümde, dinamik web sitelerinde web kazıma işleminin nasıl yapılacağını ve ilgili kavramları ayrıntılı olarak öğrenelim.

Giriş

Web kazıma karmaşık bir iştir ve web sitesi dinamikse karmaşıklık artar. Birleşmiş Milletler Küresel Web Erişilebilirlik Denetimi'ne göre web sitelerinin% 70'inden fazlası dinamiktir ve işlevleri için JavaScript'e güvenirler.

Dinamik Web Sitesi Örneği

Dinamik bir web sitesi örneğine bakalım ve kazımanın neden zor olduğunu öğrenelim. Burada, adlı bir web sitesinden arama örneği alacağızhttp://example.webscraping.com/places/default/search.Ancak bu web sitesinin dinamik bir yapıya sahip olduğunu nasıl söyleyebiliriz? Yukarıda belirtilen web sayfasından veri toplamaya çalışan aşağıdaki Python betiğinin çıktısından değerlendirilebilir -

import re
import urllib.request
response = urllib.request.urlopen('http://example.webscraping.com/places/default/search')
html = response.read()
text = html.decode()
re.findall('(.*?)',text)

Çıktı

[ ]

Yukarıdaki çıktı, örnek kazıyıcının, bulmaya çalıştığımız <div> öğesi boş olduğu için bilgi ayıklayamadığını göstermektedir.

Dinamik Web Sitelerinden Veri Toplama Yaklaşımları

Veriler JavaScript ile dinamik olarak yüklendiğinden, kazıyıcının dinamik bir web sitesindeki bilgileri kazıyamayacağını gördük. Bu gibi durumlarda, dinamik JavaScript'e bağlı web sitelerinden veri almak için aşağıdaki iki tekniği kullanabiliriz -

  • Ters Mühendislik JavaScript
  • JavaScript oluşturma

Ters Mühendislik JavaScript

Tersine mühendislik adı verilen süreç faydalı olacaktır ve verilerin web sayfaları tarafından dinamik olarak nasıl yüklendiğini anlamamızı sağlar.

Bunu yapmak için, inspect elementbelirli bir URL için sekme. Sonra tıklayacağızNETWORK Bu web sayfası için yapılan tüm istekleri bulmak için sekme, search.json dahil olmak üzere /ajax. AJAX verilerine tarayıcıdan veya NETWORK sekmesinden erişmek yerine, bunu Python betiğini takip ederek de yapabiliriz -

import requests
url=requests.get('http://example.webscraping.com/ajax/search.json?page=0&page_size=10&search_term=a')
url.json()

Misal

Yukarıdaki betik, Python json yöntemini kullanarak JSON yanıtına erişmemizi sağlar. Benzer şekilde ham dizge yanıtını indirebiliriz ve python'un json.loads yöntemini kullanarak da yükleyebiliriz. Bunu Python betiğini takip ederek yapıyoruz. Temelde, 'a' alfabesinin harfini arayarak ve ardından JSON yanıtlarının sonuç sayfalarını yineleyerek tüm ülkeleri kazıyacaktır.

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

Yukarıdaki betiği çalıştırdıktan sonra aşağıdaki çıktıyı alacağız ve kayıtlar country.txt adlı dosyaya kaydedilecektir.

Çıktı

Searching with a
adding 15 records from the page 0
adding 15 records from the page 1
...

JavaScript oluşturma

Önceki bölümde, web sayfasında API'nin nasıl çalıştığı ve sonuçları tek istekte almak için nasıl kullanabileceğimiz konusunda tersine mühendislik yaptık. Ancak tersine mühendislik yaparken aşağıdaki zorluklarla karşılaşabiliriz -

  • Bazen web siteleri çok zor olabilir. Örneğin, web sitesi Google Web Toolkit (GWT) gibi gelişmiş bir tarayıcı aracı ile yapılmışsa, ortaya çıkan JS kodu makine tarafından oluşturulur ve anlaşılması ve tersine mühendislik yapılması zor olur.

  • Gibi bazı üst düzey çerçeveler React.js Zaten karmaşık olan JavaScript mantığını soyutlayarak tersine mühendisliği zorlaştırabilir.

Yukarıdaki zorlukların çözümü, HTML'yi ayrıştıran, CSS biçimlendirmesini uygulayan ve bir web sayfasını görüntülemek için JavaScript'i çalıştıran bir tarayıcı oluşturma motoru kullanmaktır.

Misal

Bu örnekte, Java Script'i oluşturmak için tanıdık bir Python modülü Selenium kullanacağız. Aşağıdaki Python kodu, Selenium'un yardımıyla bir web sayfası oluşturacaktır -

Öncelikle, webdriver'ı selenyumdan aşağıdaki gibi içe aktarmamız gerekiyor -

from selenium import webdriver

Şimdi, ihtiyacımıza göre indirdiğimiz web sürücüsünün yolunu sağlayın -

path = r'C:\\Users\\gaurav\\Desktop\\Chromedriver'
driver = webdriver.Chrome(executable_path = path)

Şimdi, Python betiğimiz tarafından kontrol edilen o web tarayıcısında açmak istediğimiz url'yi sağlayın.

driver.get('http://example.webscraping.com/search')

Şimdi, seçilecek öğeyi ayarlamak için arama araç kutusunun kimliğini kullanabiliriz.

driver.find_element_by_id('search_term').send_keys('.')

Ardından, seçim kutusu içeriğini aşağıdaki gibi ayarlamak için java betiğini kullanabiliriz -

js = "document.getElementById('page_size').options[1].text = '100';"
driver.execute_script(js)

Aşağıdaki kod satırı, aramanın web sayfasında tıklanmaya hazır olduğunu gösterir -

driver.find_element_by_id('search').click()

Sonraki kod satırı AJAX talebini tamamlamak için 45 saniye bekleyeceğini gösterir.

driver.implicitly_wait(45)

Şimdi, ülke bağlantılarını seçmek için CSS seçiciyi aşağıdaki gibi kullanabiliriz -

links = driver.find_elements_by_css_selector('#results a')

Artık ülke listesi oluşturmak için her bağlantının metni çıkarılabilir -

countries = [link.text for link in links]
print(countries)
driver.close()