#python #beautifulsoup #pyqt #pyqt5
Вопрос:
Я пытаюсь получить дату выпуска по URL-адресу, обычные запросы и красивый суп не работают, поэтому попробуйте этот метод, и он работает только 1-й раз, но когда я запускаю его снова, дата выпуска отсутствует. Я не в состоянии понять, в чем проблема.
URL-адрес — https://www.hlj.com/gundam-universe-xxxg-01sr-gundam-sandrock-bans61272
from bs4 import BeautifulSoup as bs
import sys
from PyQt5.QtWebEngineWidgets import QWebEnginePage
from PyQt5.QtWidgets import QApplication
from PyQt5.QtCore import QUrl
class Page(QWebEnginePage):
def __init__(self, url):
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, html_str):
self.html = html_str
self.app.quit()
def __del__(self):
pass
def main():
page = Page('https://www.hlj.com/gundam-universe-xxxg-01sr-gundam-sandrock-bans61272')
soup = bs(page.html, 'html.parser')
js_test = soup.find_all('div', class_='product-date')
# js_test = js_test()
js_test = str(js_test[0])
print(js_test.splitlines())
del soup
del page
del Page._on_load_finished
if __name__ == '__main__': main()
Ответ №1:
Проблема вызвана тем, что этот HTML-код создается динамически или асинхронно, поэтому на момент загрузки страницы этот тег еще не существует. Возможное решение состоит в том, чтобы подождать, пока этот тег не будет создан с помощью QTimer и проверки с помощью метода runJavaScript:
import sys
from bs4 import BeautifulSoup as bs
from PyQt5.QtCore import QCoreApplication, QTimer, QUrl
from PyQt5.QtWidgets import QApplication
from PyQt5.QtWebEngineWidgets import QWebEnginePage
class Page(QWebEnginePage):
def __init__(self):
self.app = QApplication(sys.argv)
QWebEnginePage.__init__(self)
self._html = ""
self._js_script = ""
self.js_timer = QTimer(interval=100, singleShot=True)
self.js_timer.timeout.connect(self.handle_timeout)
self.loadFinished.connect(self._on_load_finished)
@property
def html(self):
return self._html
@property
def js_script(self):
return self._js_script
def start(self, url):
self.load(QUrl.fromUserInput(url))
QCoreApplication.instance().exec_()
@js_script.setter
def js_script(self, script):
self._js_script = script
def _on_load_finished(self):
if self.js_script:
self.js_timer.start()
else:
self.toHtml(self.handle_html)
def handle_timeout(self):
self.runJavaScript(
'document.getElementsByClassName("product-date").length > 0',
self.handle_run_js,
)
def handle_run_js(self, data):
if data:
self.toHtml(self.handle_html)
else:
self.js_timer.start()
def handle_html(self, html_str):
self._html = html_str
QCoreApplication.quit()
def main():
page = Page()
page.js_script = 'document.getElementsByClassName("product-date").length > 0'
page.start(
"https://www.hlj.com/gundam-universe-xxxg-01sr-gundam-sandrock-bans61272"
)
soup = bs(page.html, "html.parser")
js_test = soup.find("div", class_="product-date")
dt_str = js_test.find("span", class_="release-date").text
print(dt_str)
if __name__ == "__main__":
main()
Ответ №2:
Возможно, детали генерируются динамически, поэтому вы можете попытаться найти данные из xhr и извлечь их из него
Перейдите в режим разработчика Chrome и перейдите на вкладку сеть нажмите на xhr перезагрузите свой веб-сайт, и теперь ссылки появятся data
в разделе Имя, содержащем ваши данные в формате json
и когда вы нажимаете на предварительный просмотр, вы можете обнаружить, что запрос на публикацию разрешен, поэтому вы звоните в соответствии с ним!
Код:
import requests
headers={"user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36",
"referer":"https://www.hlj.com/gundam-universe-xxxg-01sr-gundam-sandrock-bans61272"}
payload={"skus": "BANS61272"}
res=requests.post("https://www.hlj.com/price_inventory/fetch/data",data=payload,headers=headers)
main_data=res.json()
main_data[payload['skus']]["release_date"]
Выход:
'May 2021'
Изображение: