python 多线程方法爬取微信公众号文章

本文在上一篇基础上增加多线程处理(http://blog.51cto.com/superleedo/2124494  )

执行思路:

1,规划好执行流程,建立两个执行线程,一个控制线程

2,线程1用于获取url,并写入urlqueue队列

3,线程2,通过线程1的url获取文章内容,并保存到本地文件中

4,线程3用于控制程序,保证1,2线程都执行完后退出

5,多线程退出程序,在子线程设置daemon为true,保证程序正常退出

6,添加异常处理,添加限时防止屏蔽

闲话不多说,上代码

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import re
import urllib.request
import time
import sys
import urllib.error
import threading
import queue

urlqueue=queue.Queue()
##模拟浏览器安装headers
headers=("User-Agent","Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36")
opener=urllib.request.build_opener()
opener.addheaders=[headers]
urllib.request.install_opener(opener)
##设置列表用于存储链接
listurl=[]

##定义代理服务器函数
#def use_proxy(proxy_addr,url):
#       try:
#               import urllib.request
#               proxy=urllib.request.ProxyHandler({'http':proxy_addr})
#               opener=urllib.request.build_opener(proxy,urllib.request.HTTPHandler)
#               urllib.request.install_opener(opener)
#               data=urllib.request.urlopen(url).read().decode('utf-8')
#               data=str(data)
#               return data
#       except urllib.error.URLError as e:
#               if hasattr(e,"code"):
#                       print(e.code)
#               if hasattr(e,"reason"):
#                       print(e.reason)
#               time.sleep(10)
#       except Exception as e:
#               print("exception"+str(e))
#               time.sleep(1)

##定义获取页面所有文章链接
class getlisturl(threading.Thread):
        def __init__(self,key,pagestart,pageend,urlqueue):
                threading.Thread.__init__(self)
                self.key=key
                self.pagestart=pagestart
                self.pageend=pageend
                self.urlqueue=urlqueue
        def run(self):

                page=self.pagestart
                keycode=urllib.request.quote(key)
        #       pagecode=urllib.request.quote("&page")
                for page in range(self.pagestart,self.pageend+1):
                        url="http://weixin.sogou.com/weixin?type=2&query="+keycode+"&page="+str(page)
                        data1=urllib.request.urlopen(url).read().decode('utf-8')
                        data1=str(data1)
                        listurlpat='<a data-z="art".*?(http://.*?)"'
                        listurl.append(re.compile(listurlpat,re.S).findall(data1))
                        time.sleep(2)
                print("共获取到"+str(len(listurl))+"页")
#               print("第2页链接数"+str(len(listurl[1]))+"个")
#               return listurl
                for i in range(0,len(listurl)):
                        time.sleep(6)
                        for j in range(0,len(listurl[i])):
                                try:
                                        url=listurl[i][j]
                                        url=url.replace("amp;","")
                                        print("第"+str(i)+"i"+str(j)+"j次入队")
                                        self.urlqueue.put(url)
                                        self.urlqueue.task_done()
                                except urllib.error.URLError as e:
                                        if hasattr(e,"code"):
                                                print(e.code)
                                        if hasattr(e,"reason"):
                                                print(e.reason)
                                        time.sleep(10)
                                except Exception as e:
                                        print("exception"+str(e))
                                        time.sleep(1)

##定义获取文章内容
class getcontent(threading.Thread):
        def __init__(self,urlqueue):
                threading.Thread.__init__(self)
                self.urlqueue=urlqueue

        def run(self):
#               i = 0
                #设置本地文件中的开始html编码
                html1 = '''
                                <!DOCTYPE html>
                                <html>
                                <head>
                                <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> 
                                <title>微信文章页面</title>
                                </head>
                                <body>
                                '''
                fh=open("/home/urllib/test/1.html","wb")
                fh.write(html1.encode("utf-8"))
                fh.close()
                #再次以追加写入的方式打开文件,以写入对应文章内容
                fh=open("/home/urllib/test/1.html","ab")
                i=1
                while(True):
                        try:
                                url=self.urlqueue.get()
                                data=urllib.request.urlopen(url).read().decode('utf-8')
                                data=str(data)
                                titlepat='var msg_title = "(.*?)";'
                                contentpat='id="js_content">(.*?)id="js_sg_bar"'
                                title=re.compile(titlepat).findall(data)
                                content=re.compile(contentpat,re.S).findall(data)
                                #初始化标题与内容
                                thistitle = "此次没有获取到"
                                thiscontent= "此次没有获取到"
                                #如果标题列表不为空,说明找到了标题,取列表第0个元素,即此次标题赋给变量thistitle
                                if (title!=[]):
                                        thistitle = title[0]
                                if (content!=[]):
                                        thiscontent = content[0]
                                #将标题与内容汇总赋给变量dataall
                                dataall = "<p>标题为:"+thistitle+"</p><p>内容为:"+thiscontent+"</p><br>"
                                fh.write(dataall.encode('utf-8'))
                                print("第"+str(i)+"个网页处理")
								time.sleep(1)
                                i+=1
                        except urllib.error.URLError as e:
                                if hasattr(e,"code"):
                                        print(e.code)
                                if hasattr(e,"reason"):
                                        print(e.reason)
                                time.sleep(10)
                        except Exception as e:
                                print("exception"+str(e))
                                time.sleep(1)

                fh.close()
                html2='''</body>
                </html>
                '''
                fh=open("/home/urllib/test/1.html","ab")
                fh.write(html2.encode("utf-8"))
                fh.close()

class contrl(threading.Thread):
        def __init__(self,urlqueue):
                threading.Thread.__init__(self)
                self.urlqueue=urlqueue
        def run(self):
                while(True):
                        print("程序执行中.....")
                        time.sleep(60)
                        if(self.urlqueue.empty()):
                                print("程序执行完毕。。。")
                                exit()

key="科技"
#proxy="122.114.31.177:808"
pagestart=1
pageend=2
#listurl=getlisturl(key,pagestart,pageend)
#getcontent(listurl)
t1=getlisturl(key,pagestart,pageend,urlqueue)
#子进程设置daemon为true,保证程序正常退出
t1.setDaemon(True)
t1.start()
t2=getcontent(urlqueue)
t2.setDaemon(True)
t2.start()
t3=contrl(urlqueue)
t3.start()

执行结果正常:

浏览器打开1.html

已上代码可以直接使用

原文地址:http://blog.51cto.com/superleedo/2124810

时间: 2024-08-01 23:13:37

python 多线程方法爬取微信公众号文章的相关文章

微信PK10平台开发与用python爬取微信公众号文章

本文通过微信提供微信PK10平台开发[q-21528-76294] 网址diguaym.com 的公众号文章调用接口,实现爬取公众号文章的功能.注意事项 1.需要安装python selenium模块包,通过selenium中的webdriver驱动浏览器获取Cookie的方法.来达到登录的效果: 2.使用webdriver功能需要安装对应浏览器的驱动插件,我这里测试用的是谷歌浏览器: google chrome版本为52.0.2743.6 ; chromedriver版本为:V2.23 注意:

使用fiddler抓取微信公众号文章的阅读数、点赞数、评论数

1 设置fiddler支持https 打开fiddler,在菜单栏中依次选择 [Tools]->[Options]->[HTTPS],勾上如下图的选项: 单击Actions,选择Export Root Certificate to Desktop(导出证书到桌面)选项: 安装证书: 在桌面上找到FiddlerRoot.cer文件,双击进行安装直到导入成功. 2 配置fiddler抓取规则 在菜单栏中依次选择 [Rules]->[Customize Rules] 弹出Fiddler Scr

爬取微信公众号内容——绘制词云

写在前面的话 前段时间写了一篇通过搜狗引擎获取微信公众号的文章,最近又看了一个网易云歌词绘制词云的程序 然后我就想,能否把这两者结合起来呢 还好经历几多波折终于把这个东西给弄出来了. 其实中间的实现不是很难, 关键是环境搭建实在是太困难了 好了,先把代码以及效果图奉献上吧 代码 weixin_spider.py #!/usr/bin/python # coding: utf-8 #这三行代码是防止在python2上面编码错误的,在python3上面不要要这样设置 import sys reloa

Python爬虫实现的微信公众号文章下载器

平时爱逛知乎,收藏了不少别人推荐的数据分析.机器学习相关的微信公众号(这里就不列举了,以免硬广嫌疑).但是在手机微信上一页页的翻阅历史文章浏览,很不方便,电脑端微信也不方便. 所以我就想有什么方法能否将这些公众号文章下载下来.这样的话,看起来也方便.但是网上的方法要么太复杂(对于我这个爬虫入门新手来说),要么付费. 但我的需求其实却很简单--"方便的查找 / 检索 / 浏览相关公众号的任意文章",所以,一番学习检索后,上手做了一个小工具(打包成可执行文件了),虽然方法和代码相当简单,但

Python 抓取微信公众号账号信息

搜狗微信搜索提供两种类型的关键词搜索,一种是搜索公众号文章内容,另一种是直接搜索微信公众号.通过微信公众号搜索可以获取公众号的基本信息及最近发布的10条文章,今天来抓取一下微信公众号的账号信息( 爬虫 首先通过首页进入,可以按照类别抓取,通过"查看更多"可以找出页面链接规则: import requests as req import re reTypes = r'id="pc_\d*" uigs="(pc_\d*)">([\s\S]*?)

如何利用Python网络爬虫爬取微信朋友圈动态--附代码(下)

前天给大家分享了如何利用Python网络爬虫爬取微信朋友圈数据的上篇(理论篇),今天给大家分享一下代码实现(实战篇),接着上篇往下继续深入. 一.代码实现 1.修改Scrapy项目中的items.py文件.我们需要获取的数据是朋友圈和发布日期,因此在这里定义好日期和动态两个属性,如下图所示. 2.修改实现爬虫逻辑的主文件moment.py,首先要导入模块,尤其是要主要将items.py中的WeixinMomentItem类导入进来,这点要特别小心别被遗漏了.之后修改start_requests方

仿微信公众号文章实现微信营销活动推广页面的方法

精仿公众号文章不是传统意义上的微信防封系统了,这是一款营销推广系统.因为对比普通网页和微信公众号文章,微信公众号文章的可信度.认知度的优势明显,于是仿公众号文章系统可以解决广大广告业主和公众号运营者在活动推广.营销推广上的问题.并且精仿公众号文章系统可实现所有内容皆可自定义和随时修改.阅读数.点赞数.留言内容等所有数据可随意设置,在灵活性上大大超越了公众号文章.   演示地址:http://www.188tool.cn/copy-articel 适用场景:分享活动,展销会活动,微信H5页面文章等

微信公众号文章抓去

微信公众号存在不少精彩的文章,如果善于挖掘,可以得到不少的收获.但由于微信对PC端的支持并不友好,虽然有搜狗搜索可以用,但其结果仍然不全,一些公众号发的不是文章类型的只是一段话,搜狗就不收录.想要得到一个账号所有的文章,还是要从爬虫着手.网上对于微信公众号文章爬取的方法几乎没有介绍,不过有几个网站,比如传送门就做出来了.这就告诉我们这个目标是可以达到的.废话不多说,直入主题. 要想得到一个公众号发送的所有文章,需要从微信手机端入手.点击公众号右上角小人图标,会有查看历史消息的链接.点了之后可查看

微信公众号文章终于聚合成信息流了

还是自己动手丰衣足食,爬了搜狗的信息,总算可以聚合微信公众号的文章内容了. 这下子一个号搞定500个最热门公众号文章,方便查阅. 接下来要去做的是信息优化. 预览版:订阅号热榜,wx_hot ======== 之前一直有声音称,微信公众号目前的模式,很不适合大量关注的用户查看每日更新的文章.所以造成了大量的公众号订阅号被折叠以后,鲜有人问津.一旦打开订阅号,会发现众多“…”标记的公众号,这些都是未读条数超过99条的账号. 面对折叠以后,造成阅读量下降,难道微信就任其发展不顾么? 事情显然是否定的