Соскребая веб-страницу JavaScript с Python - PullRequest
145 голосов
/ 08 ноября 2011

Я пытаюсь разработать простой веб-скребок.Я хочу извлечь текст без кода HTML.Фактически, я достигаю этой цели, но я видел, что на некоторых страницах, где загружен JavaScript, я не получил хороших результатов.

Например, если какой-то код JavaScript добавляет какой-то текст, я не вижупотому что, когда я звоню

response = urllib2.urlopen(request)

, я получаю исходный текст без добавленного (потому что JavaScript выполняется в клиенте).

Итак, я ищу некоторые идеи длярешить эту проблему.

Ответы [ 12 ]

4 голосов
/ 30 мая 2018

Смесь BeautifulSoup и Selenium работает для меня очень хорошо.

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from bs4 import BeautifulSoup as bs

driver = webdriver.Firefox()
driver.get("http://somedomain/url_that_delays_loading")
    try:
        element = WebDriverWait(driver, 10).until(
        EC.presence_of_element_located((By.ID, "myDynamicElement"))) #waits 10 seconds until element is located. Can have other wait conditions  such as visibility_of_element_located or text_to_be_present_in_element

        html = driver.page_source
        soup = bs(html, "lxml")
        dynamic_text = soup.find_all("p", {"class":"class_name"}) #or other attributes, optional
    else:
        print("Couldnt locate element")

PS Вы можете найти больше условий ожидания здесь

1 голос
/ 14 июля 2018

Использование PyQt5

from PyQt5.QtWidgets import QApplication
from PyQt5.QtCore import QUrl
from PyQt5.QtWebEngineWidgets import QWebEnginePage
import sys
import bs4 as bs
import urllib.request


class Client(QWebEnginePage):
    def __init__(self,url):
        global app
        self.app = QApplication(sys.argv)
        QWebEnginePage.__init__(self)
        self.html = ""
        self.loadFinished.connect(self.on_load_finished)
        self.load(QUrl(url))
        self.app.exec_()

    def on_load_finished(self):
        self.html = self.toHtml(self.Callable)
        print("Load Finished")

    def Callable(self,data):
        self.html = data
        self.app.quit()

#url = ""
#client_response = Client(url)
#print(client_response.html)
...