python爬取搜狗微信的推文

  • Post author:
  • Post category:python


模块背景: 项目评估 中需要将所有发布在公众号的里的文章截图,然后放在文档中留档,比如:将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&timestamp=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()

最后再分享一篇文章


不要触犯法律,编写安全爬虫的几点建议



版权声明:本文为winson20102010原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。