PyQt5 抓取 IMDb 网页
Posted
技术标签:
【中文标题】PyQt5 抓取 IMDb 网页【英文标题】:PyQt5 to scrape IMDb webpage 【发布时间】:2018-04-17 13:02:01 【问题描述】:我现在已经开始使用 python 进行 Web Scraping,我想从这个 link 中抓取图像。这是screenshot of "Inspect"。 这是我尝试过的代码,因为它涉及 javascript。
import bs4 as bs
import sys
import urllib.request
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 main():
page = Page('https://www.imdb.com/name/nm0005683/mediaviewer/rm2073384192')
soup = bs.BeautifulSoup(page.html, 'html.parser')
imagetag = soup.find('div', id='photo-container')
print (imagetag)
if __name__ == '__main__': main()
这段代码实际上来自here,我只是修改了链接
我遇到的错误
js: Uncaught TypeError: Cannot read property 'x' of undefined
Load finished
<div id="photo-container"></div>
我不知道实际的错误是什么,内容没有显示我确实尝试用谷歌搜索错误但找不到任何可以帮助这种情况的东西。另外,如果我应该尝试任何其他方法来抓取图像而不是这个,我也愿意接受这些建议。
PS:我也是 *** 的新手,所以如果这里有任何不违反规则的内容,我可以根据需要编辑问题。
【问题讨论】:
我会说 TypeError 是一个红鲱鱼。抓取页面的问题是页面通常存在大多数良性问题。你的代码做了你要求它做的事情。 TypeError 可能是您在浏览器中查看控制台输出时看到的正常输出。 @shao.lo 如果它完成了我要求它做的事情,那么我如何显示它所做的事情?由于该错误,print (imagetag)
没有显示<div>
的完整内容
BeautifulSoup 将处理原始 html。页面上呈现的内容通常由 javascript 动态填充。如果您查看页面源代码,您会发现情况就是如此。要获取实际内容,您需要通过 javascript 在页面中执行此操作。
【参考方案1】:
您可能希望使用网络频道来完成实际工作,但下面将向您展示如何访问您正在寻找的图像。我将把网络频道研究留给你。
import sys
from PyQt5.QtWebEngineWidgets import QWebEngineView, QWebEnginePage
from PyQt5.QtWidgets import QApplication
from PyQt5.QtCore import QUrl, QTimer
class Page(QWebEnginePage):
def __init__(self, parent):
QWebEnginePage.__init__(self, parent)
self.html = ''
self.loadFinished.connect(self._on_load_finished)
def _on_load_finished(self):
print('Load finished')
QTimer.singleShot(1000, self._after_loading) # load finished does not mean rendered..may need to wait here
QTimer.singleShot(5000, self._exit)
def _after_loading(self):
print('_after_loading')
js = '''console.log('javascript...');
var images = document.querySelectorAll('#photo-container img');
console.log('images ' + images);
console.log('images ' + images.length);
for (var i = 0; i < images.length; i++)
var image = images[i];
console.log(image.src);
var element = document.querySelector('body');
//console.log(element.innerHTML); // If you uncomment this you'll see the the photo-container is still empty
'''
self.runJavaScript(js)
print('_after_loading...done')
def _exit(self):
print('_exit')
QApplication.instance().quit()
def javaScriptConsoleMessage(self, level: QWebEnginePage.JavaScriptConsoleMessageLevel, message: str, lineNumber: int, sourceID: str):
print(message)
def main():
app = QApplication(sys.argv)
w = QWebEngineView()
w.setPage(Page(w))
w.load(QUrl('https://www.imdb.com/name/nm0005683/mediaviewer/rm2073384192'))
w.show()
app.exec_()
if __name__ == '__main__': main()
【讨论】:
以上是关于PyQt5 抓取 IMDb 网页的主要内容,如果未能解决你的问题,请参考以下文章