Python'da bir JavaScript web sitesi nasıl kazınır?

Sep 06 2020

Bir web sitesini kazımaya çalışıyorum. İki yöntem kullanmayı denedim, ancak ikisi de bana aradığım web sitesi kaynak kodunu tam olarak sağlamıyor. Aşağıda verilen web sitesi URL'sinden haber başlıklarını kazımaya çalışıyorum.

URL: "https://www.todayonline.com/"

Bunlar denediğim ancak başarısız olduğum iki yöntem.

Yöntem 1: Güzel Çorba

tdy_url = "https://www.todayonline.com/"
page = requests.get(tdy_url).text
soup = BeautifulSoup(page)
soup  # Returns me a HTML with javascript text
soup.find_all('h3')

### Returns me empty list []

Yöntem 2: Selenyum + BeautifulSoup

tdy_url = "https://www.todayonline.com/"

options = Options()
options.headless = True

driver = webdriver.Chrome("chromedriver",options=options)

driver.get(tdy_url)
time.sleep(10)
html = driver.page_source

soup = BeautifulSoup(html)
soup.find_all('h3')

### Returns me only less than 1/4 of the 'h3' tags found in the original page source 

Lütfen yardım et. Diğer haber sitelerini taramayı denedim ve çok daha kolay. Teşekkür ederim.

Yanıtlar

2 politicalscientist Sep 06 2020 at 15:38

Verilere API aracılığıyla erişebilirsiniz (Ağ sekmesine bakın):


Örneğin,

import requests
url = "https://www.todayonline.com/api/v3/news_feed/7"
data = requests.get(url).json()
2 Noname Sep 06 2020 at 15:39

Javascript içeren bir web sayfasının içeriğini toplamanın farklı yolları vardır.

  1. seleniumFirefox web sürücüsüyle kullanmak
  2. Başsız bir tarayıcı kullanmak phantomJS
  3. REST istemcisi veya python requestskitaplığı kullanarak bir API çağrısı yapmak

Önce araştırmanı yapmalısın

2 MananGajjar Sep 06 2020 at 16:04

Size oldukça basit bir yaklaşım önereceğim,

import requests
from bs4 import BeautifulSoup as bs

page = requests.get('https://www.todayonline.com/googlenews.xml').content
soup = bs(page)
news = [i.text for i in soup.find_all('news:title')]

print(news)

çıktı

['DBS named world’s best bank by New York-based financial publication',
 'Russia has very serious questions to answer on Navalny - UK',
 "Exclusive: 90% of China's Sinovac employees, families took coronavirus vaccine - CEO",
 'Three militants killed after fatal attack on policeman in Tunisia',
.....]

Ayrıca, gerekirse daha fazla bilgi için XML sayfasını kontrol edebilirsiniz.

PS Herhangi bir web sitesini hurdaya çıkarmadan önce her zaman uyumluluğu kontrol edin :)

2 DemianWolf Sep 06 2020 at 16:00

Kazımaya çalıştığınız web sitesindeki haber verileri sunucudan JavaScript kullanılarak alınır (buna XHR - XMLHttpRequest denir ). Sayfa yüklenirken veya kaydırılırken dinamik olarak oluyor. bu nedenle bu veriler sunucu tarafından döndürülen sayfanın içinde döndürülmez.

İlk örnekte, yalnızca sunucu tarafından döndürülen sayfayı - haberler olmadan, ancak onları alması gereken JS ile - alıyorsunuz. Ne istekler ne de BeautifulSoup JS'yi yürütemez.

Ancak, haber başlıklarını sunucudan alan istekleri Python istekleriyle yeniden üretmeyi deneyebilirsiniz. Aşağıdaki adımları uygulayın:

  1. Tarayıcınızın DevTools'u açın (bunun için genellikle F12veya Ctrl+ Shit+ tuşlarına basmanız gerekir I) ve sunucudan haber başlıkları alan isteklere bir göz atın. Bazen, BeautifulSoup ile web kazımadan daha kolaydır. İşte bir ekran görüntüsü (Firefox):
  1. İstek bağlantısını kopyalayın (sağ tıklayın -> Kopyala -> Bağlantıyı kopyala) ve iletin requests.get(...).

  2. .json()İsteği alın . Üzerinde çalışılması kolay bir söz döndürecektir. Kararın yapısını daha iyi anlamak için pprintbasit baskı yerine kullanmanızı tavsiye ederim . from pprint import pprintKullanmadan önce yapmanız gerektiğini unutmayın .

Sayfadaki ana haberlerden başlıkları alan koda bir örnek:

import requests


nodes = requests.get("https://www.todayonline.com/api/v3/news_feed/7")\
        .json()["nodes"]
for node in nodes:
    print(node["node"]["title"])

Bir haber grubunu news_feed/altyazının altına almak istiyorsanız, istek URL'sinden sonraki sayıyı değiştirmeniz gerekir (bunu elde etmek için, istekleri DevTools'ta "news_feed" e göre filtrelemeniz ve haber sayfasını aşağı kaydırmanız yeterlidir).

Bazen web sitelerinin botlara karşı koruması vardır (ancak kazımaya çalıştığınız web sitesi olmasa da). Bu gibi durumlarda, bu adımları da uygulamanız gerekebilir .