Python自学笔记——多线程微信文章爬取
# -*- coding: utf-8 -*-
"""
Created on Tue Dec 26 10:34:09 2017
@author: Andrew
"""
#线程1专门获取对应网址并处理为真是网址,然后将网址写入队列urlqueue中,该队列专门用来存放具体文章的网址
#线程2与线程1并行,从线程1提供的网址中依次爬取对应文章信息并处理,处理后将我们需要的结果写入对应的本地文件中
#线程3主要用于判断程序是否完成。因为在此如果没有一个总体控制的线程,即使线程1、2执行完,也不会退出程序
#在正规的项目设计时,尽量并行执行的线程执行的时间相近
#建立合理的延时机制,如:发生异常或让执行较快的线程进行延时。
#建立合理的异常处理机制
导入所需的模块
import threading
import queue
import re
import urllib.request
import time
import urllib.error
#创建一个网址队列
urlqueue=queue.Queue()
#模拟成浏览器
headers=("User-Agent","Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.94 Safari/537.36")
opener.add_handler=[headers]
#将opener安装为全局
#建立空url列表
listurl=[]
#读取网页源代码
def readdata(url):
try:
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)
#线程1,专门获取对应网址并处理为真实网址
class geturl(threading.Thread):
def __init__(self,key,pagestart,pageend,urlqueue):
threading.Thread.__init__(self)
self.pagestart=pagestart
self.pageend=pageend
self.urlqueue=urlqueue
def run(self):
page=self.pagestart
#编译关键词key
for page in range(self.pagestart,self.pageend+1):
data1=readdata(url)
#列表页url正则
listurlpat='
.*?(http://.*?)"'
listurl.append(re.compile(listurlpat,re.S).findall(data1))
#便于调试
print("获取到"+str(len(listurl))+"页")
for i in range(0,len(listurl)):
#等一等线程2,合理分配资源
time.sleep(7)
for j in range(0,len(listurl[i])):
try:
url=listurl[i][j]
#处理成真实url,采集网址比真实网址多了一串"amp;"
url=url.replace("amp;","")
print("第"+str(i)+","str(j)+"次入队")
except urllib.error.URLError as e:
if hasattr(e,"code"):
print(e.code)
if hasattr(e,"reason"):
print(e.reason)
#若为URLError异常,延时10秒执行
time.sleep(10)
except Exception as e:
print("exception:"+str(e))
#若为Exception异常,延时1秒执行
time.sleep(1)
#线程2,与线程1并行,从线程1提供的网址urlqueue中依次爬去对应文章信息并处理
class getcontent(threading.Thread):
def __init__(self,urlqueue):
threading.Thread.__init__(self)
self.urlqueue=urlqueue
def run(self):
html='''
fh=open("C:/Python35/3.html","wb")
fh.write(html.encode("utf-8"))
fh.close()
fh=open("C:/Python35/3.html","ab")
i=1
while(True):
try:
data=readdata(url)
#文章标题正则表达式
titlepat="(.*?)"
#文章内容正则表达式
contentpat='id="js_content">(.*?)id="js_sg_bar"'
#通过对应正则表达式找到标题并赋给列表title
title=re.compile(titlepat).findall(data)
#通过对应正则表达式找到内容并赋给content
content=re.compile(contentpat,re.S).findall(data)
#初始化标题与内容
thistitle="此次没有获取到"
thiscontent="此次没有获取到"
#如果标题列表不为空,说明找到了标题,去列表第0个元素,即次标题赋给thistitle
if(title!=[]):
thistitle=title[0]
if(thiscontent!=[]):
thiscontent=content[0]
#将标题与内容汇总赋给变量dataall
dataall="
标题为:"+thistitle+"
内容为:"+thiscontent+"
"
#将该篇文章的标题与内容的总信息写入对应文件
fh.write(dataall.encode("utf-8"))
print("第"+str(i)+"个网页")#便于调试
i+=1
except urllib.error.URLError as e:
if hasattr(e,"code"):
print(e.code)
if hasattr(e,"reason"):
print(e.reason)
#若为URLError异常,延时10秒执行
time.sleep(10)
except Exception as e:
print("exception:"+str(e))
#若为Exception异常,延时1秒执行
time.sleep(1)
fh.close()
html4='''
'''
fh=open("C:/Python35/3.html","ab")
fh.write(html4.encode("utf-8"))
fh.close()
#并行控制程序,若60秒未响应,并且url的队列已空,则判断为执行成功
class contrl(threading.Thread):
def __init__(self,urlqueue):
threading.Thread.__init__(self)
self.urlqueue=urlqueue
def run(self):
while(True):
print("程序执行中")
time.sleep(60)
print("程序执行完毕!")
exit()
#运行
key="考研数学泄题"
pagestart=1#起始页
pageend=2#爬取到哪页
#创建线程1对象,随后启动线程1
t1=geturl(key,pagestart,pageend,urlqueue)
t1.start()
#创建线程2对象,随后启动线程2
t2=getcontent(urlqueue)
t2.start()
#创建线程3对象,随后启动线程3
t3=contrl(urlqueue)
t3.start()
- 美团点评SQL优化工具SQLAdvisor开源
- 美团外卖前端可视化界面组装平台 —— 乐高
- Android自定义Lint实践2——改进原生Detector
- 布局编码的未来
- 美团点评前端无痕埋点实践
- Android远程调试的探索与实现
- Redux从设计到源码
- Golang语言社区--Golang通用连接池
- 学习笔记CB009:人工神经网络模型、手写数字识别、多层卷积网络、词向量、word2vec
- 本周群问题分享
- 干货 | 一篇文章教你用TensorFlow写名著
- 开发图片预加载框架
- 机器学习之分类问题实战(基于UCI Bank Marketing Dataset)
- python笔记:#013#高级变量类型
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 推荐系统中的常用算法——DeepWalk算法
- TypeError: cannot unpack non-iterable NoneType object
- 原型模式
- Spring 整合 Mybatis
- 数据库PostrageSQL-关闭服务器
- 快速配置Azure DevOps代理服务器
- 数据库PostrageSQL-管理内核资源
- airtest操作夜神模拟器adb冲突解决办法
- 数据库PostrageSQL-启动数据库服务器
- 数据库PostrageSQL-PostgreSQL用户账户创建一个数据库集簇
- 轻松上手SpringBoot Security + JWT Hello World示例
- [Go] Golang发送http GET请求
- Windows系统快速安装Superset 0.37
- 商业数据分析从入门到入职(3)Excel进阶应用
- python列表练习