采用PyQt5+urllib3+BeautifulSoup4进行动态网页的图片抓取爬虫
心血来潮,想在某个网站抓取图片,结果用requests下载下来,却发现,里面不含有图片,也就是说,图片全是由js等代码放到页面上去的,所以,requests下载的页面并没有执行js内容,于是就不能从里面找到所要的图片。为了解决这个问题,聪明的网友们发现用PyQt的网页相关模块可以解决这个问题,而不需要用selenium等模块操作浏览器,于是乎,参考了一些文章,终于达到了我的目的。于是在这里记录相关步骤,也可给各位一个参考。
本文基于以下环境和版本:
Windows 7
Python3.6.0 x32
Python模块:
beautifulsoup4==4.6.0
urllib3==1.22
PyQt5==5.10.1
注:PyQt5.8.2也测试通过
IDE:PyCharm3.2
首先,准备好测试用的HTML等文件
main.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Main Page</title>
</head>
<body>
<div>这是主页</div>
<script type="text/javascript" src="./main.js"></script>
</body>
</html>
main.js
function dynamicImg(img_url)
{
var div = document.createElement("div");
div.innerText = img_url;
var img = document.createElement("img");
img.src = img_url;
img.classList.add("test");
document.body.appendChild(div);
document.body.appendChild(img);
}
// 用js在页面上添加两张图片
dynamicImg("./test1.jpg");
dynamicImg("./test2.png");
图片请自己准备。将html,js,jpg等文件放到某个文件夹下,比如我的存放位置看下图浏览器地址栏。
本地用浏览器打开之后,效果如下(图片较大,截了一部分):
以下代码均在文件app.py中
以下代码用到的库:
import urllib.request
import urllib.response
import random
import bs4 as bs
import os
import sys
from PyQt5.QtWebEngineWidgets import QWebEnginePage
from PyQt5.QtWidgets import QApplication
from PyQt5.QtCore import QUrl
如果用request直接下载的效果:
def useRequestMethod(url):
"""
传统方法不能下载动态网页
"""
response = urllib.request.urlopen(url)
with open("download.html", "w+", encoding="utf-8") as f:
f.write(response.read().decode("utf-8"))
if __name__ == '__main__':
url = "file:///E:/Code/Python/SimpleCrawler/CrawlerImageExample/main.html"
useRequestMethod(url)
上述代码将下载的HTML存入了download.html中,打开看一下:
可以看到,下载下来的HTML并没有执行JS代码,导致HTML中根本不含图片链接,于是这个时候,就该PyQt5出场了。
使用PyQt5下载js执行过后的动态页面
这里封装了一个类,用PyQt5的QWebEnginePage去加载url并等url完全执行完毕后,得到这个url的整个HTML
class MyWebBrowser(QWebEnginePage):
app = None
# 类变量 QApplication
# 实际测试时,若调用了多个MyWebBrowser对象(有先后顺序的调用)
# 比如现在某些页面上,获取了所有包含图片的页面链接,再去打开这些链接上抓取图片
# 容易在这一步 super(