Python多线程爬虫
前言
用上多线程,感觉爬虫跑起来带着风
运行情况
爬取了9万多条文本记录,耗时比较短,一会儿就是几千条
关键点
多个线程对同一全局变量进行修改要加锁
# 获取锁,用于线程同步
threadLock.acquire()
global htmlId
htmlId=htmlId+1
self.htmlId=htmlId
# 释放锁
threadLock.release()
改进
如果因为某种原因爬取失败,这个爬虫并未对失败原因进行记录,所以不方便对漏网之鱼重新爬取。而且由于对方的反爬虫机制,每爬取5000多条时发现对方没有响应,此时应该插入等待时间。
代码
# coding:UTF-8
# https://******.com/article/91510.html
from bs4 import BeautifulSoup
import requests
import threading
import time
htmlId=70570
class Spider(threading.Thread):
def __init__(self, threadID, name):
threading.Thread.__init__(self)
self.threadID = threadID
self.name = name
'''
logging.basicConfig(level=logging.DEBUG,#控制台打印的日志级别
filename='new.log',
filemode='a',##模式,有w和a,w就是写模式,每次都会重新写日志,覆盖之前的日志
#a是追加模式,默认如果不写的话,就是追加模式
format='%(asctime)s - %(pathname)s[line:%(lineno)d] - %(levelname)s: %(message)s'
#日志格式
)
'''
self.targetURL='https://******.com/article/'
self.header={'User-Agent':'Mozilla/4.0 (compatible; MSIE 5.5; Windows NT)'}
threadLock.acquire()
global htmlId
self.htmlId=htmlId
threadLock.release()
def nextURL(self):
# 获取锁,用于线程同步
threadLock.acquire()
global htmlId
htmlId=htmlId+1
self.htmlId=htmlId
# 释放锁
threadLock.release()
url=self.targetURL+str(self.htmlId)+'.html'
return url
def getHtml(self,url):
try:
html=requests.get(url,headers=self.header,timeout=10).text
return html
except:
#logging.warning('warning: id= '+str(self.htmlId)+' can\'t connect!')
return url
def parserHtml(self,html):
try:
bf = BeautifulSoup(html)
title=bf.find_all('title')[0].text
content=bf.find_all('div', class_ = 'img-center')[0].text
return title,content
except:
#logging.warning('warning: id= '+str(self.htmlId)+' can\'t parser!')
return str(self.htmlId),str(self.htmlId)
def saveContent(self,title,content):
try:
with open("./fiction/"+title+'.html','a') as f:
content=title+'\r\n'+content
f.write(content)
#logging.info('success: id= '+str(self.htmlId)+' '+title)
except:
#logging.warning('warning: id= '+str(self.htmlId)+' failed to save content!')
self.relax()
def finishCondition(self):
if(self.htmlId>=91510):
return True
else:
return False
def relax(self):
time.sleep(5)
def run(self):
print ("开启线程: " + self.name)
'''
# 获取锁,用于线程同步
threadLock.acquire()
# 释放锁,开启下一个线程
threadLock.release()
'''
while(not self.finishCondition()):
url=self.nextURL()
print(url)
html=self.getHtml(url)
title,content=self.parserHtml(html)
self.saveContent(title,content)
if __name__ == "__main__":
threadLock = threading.Lock()
threads = []
i=1
num=51
# 创建新线程
for item in range(num):
exp="thread"+str(i)+" = "+"Spider("+str(i)+","+"\"Thread-"+str(i)+"\")"
exec(exp)
i=i+1
i=1
for item in range(num):
exp="thread"+str(i)+".start()"
exec(exp)
i=i+1
i=1
for item in range(num):
exp="threads.append(thread"+str(i)+")"
exec(exp)
i=i+1
'''
thread1 = Spider(1, "Thread-1")
# 开启新线程
thread1.start()
# 添加线程到线程列表
threads.append(thread1)
'''
# 等待所有线程完成
for t in threads:
t.join()
print ("退出主线程")
print (htmlId)
'''
target = 'https://******.com/article/91510.html'
req = requests.get(url = target)
html = req.text
bf = BeautifulSoup(html)
texts = bf.find_all('div', class_ = 'img-center')
print(texts[0].text)
'''
Python多线程爬虫的更多相关文章
- python多线程爬虫+批量下载斗图啦图片项目(关注、持续更新)
python多线程爬虫项目() 爬取目标:斗图啦(起始url:http://www.doutula.com/photo/list/?page=1) 爬取内容:斗图啦全网图片 使用工具:requests ...
- python多线程爬虫设计及实现示例
爬虫的基本步骤分为:获取,解析,存储.假设这里获取和存储为io密集型(访问网络和数据存储),解析为cpu密集型.那么在设计多线程爬虫时主要有两种方案:第一种方案是一个线程完成三个步骤,然后运行多个线程 ...
- Python多线程爬虫与多种数据存储方式实现(Python爬虫实战2)
1. 多进程爬虫 对于数据量较大的爬虫,对数据的处理要求较高时,可以采用python多进程或多线程的机制完成,多进程是指分配多个CPU处理程序,同一时刻只有一个CPU在工作,多线程是指进程内部有多个类 ...
- Python多线程爬虫爬取电影天堂资源
最近花些时间学习了一下Python,并写了一个多线程的爬虫程序来获取电影天堂上资源的迅雷下载地址,代码已经上传到GitHub上了,需要的同学可以自行下载.刚开始学习python希望可以获得宝贵的意见. ...
- python 多线程爬虫
最近,一直在做网络爬虫相关的东西. 看了一下开源C++写的larbin爬虫,仔细阅读了里面的设计思想和一些关键技术的实现. 1.larbin的URL去重用的很高效的bloom filter算法: 2. ...
- Python多线程爬虫爬取网页图片
临近期末考试,但是根本不想复习!啊啊啊啊啊啊啊!!!! 于是做了一个爬虫,网址为 https://yande.re,网页图片为动漫美图(图片带点颜色........宅男福利 github项目地址为:h ...
- Python多线程爬虫详解
一.程序进程和线程之间的关系 程序:一个应用就是一个程序,比如:qq,爬虫 进程:程序运行的资源分配最小单位, 很多人学习python,不知道从何学起.很多人学习python,掌握了基本语法过后,不知 ...
- python 多线程爬虫 实例
多进程 Multiprocessing 模块 Process 类用来描述一个进程对象.创建子进程的时候,只需要传入一个执行函数和函数的参数即可完成 Process 示例的创建. star() 方法启动 ...
- python多线程爬虫:亚马逊价格
import re import requests import threading import time from time import ctime,sleep from queue impor ...
随机推荐
- 谈谈Groovy闭包
A closure is a function with variables bound to a context or environment in which it executes. 概述 闭包 ...
- HDU 1233 还是畅通工程 (最小生成树 )
某省调查乡村交通状况,得到的统计表中列出了任意两村庄间的距离.省政府“畅通工程”的目标是使全省任何两个村庄间都可以实现公路交通(但不一定有直接的公路相连,只要能间接通过公路可达即可),并要求铺设的公路 ...
- node.js读取到的文件列表
var fs = require('fs'); var path = require('path'); //解析需要遍历的文件夹,我这以E盘根目录为例 var filePath = path.reso ...
- 单例设计模式 --c#
单例设计模式:在单例设计模式中我们要保持对象始终是唯一的 参考代码: class SingleObject { private SingleObject() { } private static Si ...
- NUL和NULL
此处讨论C语言中的NUL和NULL 1.NUL是ASCII字符集中'\0'字符的名字,它的字节模式为全0 2.NULL指一个其值为0的指针 3.它们都是整型值,其值也相同,所以可以互换使用 4.然而, ...
- myBatis框架之入门(一)
什么是框架 框架就是一个架子,表演节目,舞台已经搭建好,表演什么节目,看自己的需求了. 框架是一个半成品,对于Java语言来说,框架就是封装了别人的代码.在框架的基础上我们在进一步开发,拿来主义. 框 ...
- 关于nginx配置虚拟主机
前提:我的虚拟主机的外网ip为111.231.226.228(是云服务器哈) 本地测试环境为windows7(修改本地的hosts文件) 步骤:(安装nginx可以看看我文章“linux ng ...
- Golang字符串函数认识(一)
package main import ( "fmt" "strings" "strconv" ) func main(){ //返回字符串 ...
- ORA-00600: internal error code, arguments: [13030], [20]一例解决
两年没有接触oracle了,中午,一环境update from的时候出现ORA-00600: internal error code, arguments: [13030], [20]异常,经查,官网 ...
- Sublime Text安装与配置
1.1 下载安装Sublime Text 3 参考博客:https://www.cnblogs.com/Rising/p/3741116.html 1.下载安装Sublime Text 3 1. 下 ...