Python'da bir JavaScript web sitesi nasıl kazınır?
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
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()
Javascript içeren bir web sayfasının içeriğini toplamanın farklı yolları vardır.
seleniumFirefox web sürücüsüyle kullanmak- Başsız bir tarayıcı kullanmak
phantomJS - REST istemcisi veya python
requestskitaplığı kullanarak bir API çağrısı yapmak
Önce araştırmanı yapmalısın
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 :)
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:
- 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):
İstek bağlantısını kopyalayın (sağ tıklayın -> Kopyala -> Bağlantıyı kopyala) ve iletin
requests.get(...)..json()İsteği alın . Üzerinde çalışılması kolay bir söz döndürecektir. Kararın yapısını daha iyi anlamak içinpprintbasit 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 .