模块背景: 项目评估 中需要将所有发布在公众号的里的文章截图,然后放在文档中留档,比如:将CSDN公众号在2021中推送过所有包含”python”文章截图保存到本地
模块目的:将一定时间内,该公众号推送过的文章,截图保存,最后可以打包下载到本地
使用技术:python+flask+BeautifulSoup+selenium
python+flask 主要负责web 方面搭建
BeautifulSoup 负责 解析html
selenium 负责执行自动化,操作浏览器实现截图
因为如果需要爬取指定公众号的推文,根据网上的说法需要进去公众号后台,这是不可能。可以用搜狗搜索,里面有微信推文搜索的,例如这样:
从这里可以查找到,标题,来源,发布时间,甚至是推文的链接,可以先将数据保存到数据库,接着看:
一共有5327条数据,每页10条,就是说有533页
https://weixin.sogou.com/weixin?query=%E6%A1%82%E5%9F%8E&_sug_type_=&sut=1109&lkt=1%2C1641977435904%2C1641977435904&s_from=input&_sug_=n&type=2&sst0=1641977436006&page=2&ie=utf8&w=01019900&dr=1
复制地址下来 page=2,就是代表第2页,只要不断递增page访问,就会跳到其他页,
这里要注意了,如果没有登录,最多只能访问10页,如果登录了,最多只能访问40次,搜狗为了防止爬虫,连续访问超过40次,就需要填写验证码!
后台的界面如下:
就是根据关键字,活动日期,来源,页数(循环page)
打开的每一页都先保存整页的代码,然后再用BeautifulSoup解析html,抽出标题,地址,来源,发布时间,然后再保存起来,就想这样
这是爬下来的地址:
https://weixin.sogou.com/link?url=dn9a_-gY295K0Rci_xozVXfdMkSQTLW6cwJThYulHEtVjXrGTiVgSy5i4o3HOD95thpaGWmhkkbo7yR4r1H3yVqXa8Fplpd9RxRNe_xjkVJJiE06A_4_OZVgTUm0Q2_1d4yG1C1ugpVNVWBFvtvlqZjQPBBg9WpzON77MSUhok9RDhFsWvPTsSsyOXRvQR48kkrZ4kZtDXTBJ0dgk2uZA24_oAUwF09FPwN1ZRbubnE-KQa8AyDHiprLiPUoUjb4fDZm9ioL0qRf_71bqkOtiw…&type=2&query=%E6%A1%82%E5%9F%8E&token=2C8C2BA2EC35C7B6CFCA1A9064D7471BCF801E1661DE9B4D&k=66&h=X
这是实际打开的地址:
https://mp.weixin.qq.com/s?src=11×tamp=1641978701&ver=3554&signature=qq3XrTiEvrtvKWGOEAxt95FveuErHjs-iAhTyFA4bhSE2LEEDLk81EGfzhfCFUbspjTt4ITcZK
myfo8jPL3tBPpN2F5aneIMXmdSoMvHe30Qumh0o133Ay33I
Gcayj&new=1
明显是做了重定向,而且如果用selenium操作weixin.sogou.com,搜狗会检测到的,会直接跳去验证码,但是如果用selenium执行mp.weixin.qq.com的地址,是无问题的,因为已经跳到微信,那就是说,我需要将所有搜狗的地址转换成微信地址。
解决办法:
我用postman 执行 上面搜狗的地址:
返回这段JS
setTimeout(function () {
var url = '';
url += 'http://mp.w';
url += 'eixin.qq.co';
url += 'm/s?src=11&';
url += 'timestamp=1';
url += '641978701&v';
url += 'er=3554&sig';
url += 'nature=qq3X';
url += 'rTiEvrtvKWG';
url += 'OEAxt95Fveu';
url += 'ErHjs-iAhTy';
url += 'FA4bhSE2LEEDLk81EGfzhfCFUbspjTt4ITcZK*myfo8jPL3tBPpN2F5aneIMXmdSoMvHe30Qumh0o133Ay33I*Gcayj&new=1';
url.replace("@", "");
window.location.replace(url)
},100);
将所有url 拼接在一起的,就是微信的地址了!Postman可以生成requests方法
更新了所有文章的地址后,可以将文章截图(截图方法博客有)存放在指定的文件夹,然后将文件全部读出去,如下:
分享一个压缩打包下载的方法
@files_bp.route('/downloadzip',methods=['GET'])
@login_required
def downloadzip():
now = int(time.time())
filename = str(now)+".zip"
fileUrl = sys.path[0]+r'\screenshots/'
zipFile = sys.path[0]+r"/"+filename
zipDir(fileUrl,zipFile)
zip_data = open(zipFile, "rb").read()
response = make_response(zip_data)
response.headers["Content-Disposition"] = "attachment; filename={}".format(filename.encode().decode('utf-8'))
return response
#压缩方法
def zipDir(dirpath,outFullName):
import zipfile
"""
压缩指定文件夹
:param dirpath: 目标文件夹路径
:param outFullName: 压缩文件保存路径+xxxx.zip
:return: 无
"""
zip = zipfile.ZipFile(outFullName,"w",zipfile.ZIP_DEFLATED)
for path,dirnames,filenames in os.walk(dirpath):
# 去掉目标跟路径,只对目标文件夹下边的文件及文件夹进行压缩
fpath = path.replace(dirpath,'')
for filename in filenames:
zip.write(os.path.join(path,filename),os.path.join(fpath,filename))
zip.close()
最后再分享一篇文章
不要触犯法律,编写安全爬虫的几点建议