前言

用上多线程,感觉爬虫跑起来带着风

运行情况

爬取了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多线程爬虫的更多相关文章

  1. python多线程爬虫+批量下载斗图啦图片项目(关注、持续更新)

    python多线程爬虫项目() 爬取目标:斗图啦(起始url:http://www.doutula.com/photo/list/?page=1) 爬取内容:斗图啦全网图片 使用工具:requests ...

  2. python多线程爬虫设计及实现示例

    爬虫的基本步骤分为:获取,解析,存储.假设这里获取和存储为io密集型(访问网络和数据存储),解析为cpu密集型.那么在设计多线程爬虫时主要有两种方案:第一种方案是一个线程完成三个步骤,然后运行多个线程 ...

  3. Python多线程爬虫与多种数据存储方式实现(Python爬虫实战2)

    1. 多进程爬虫 对于数据量较大的爬虫,对数据的处理要求较高时,可以采用python多进程或多线程的机制完成,多进程是指分配多个CPU处理程序,同一时刻只有一个CPU在工作,多线程是指进程内部有多个类 ...

  4. Python多线程爬虫爬取电影天堂资源

    最近花些时间学习了一下Python,并写了一个多线程的爬虫程序来获取电影天堂上资源的迅雷下载地址,代码已经上传到GitHub上了,需要的同学可以自行下载.刚开始学习python希望可以获得宝贵的意见. ...

  5. python 多线程爬虫

    最近,一直在做网络爬虫相关的东西. 看了一下开源C++写的larbin爬虫,仔细阅读了里面的设计思想和一些关键技术的实现. 1.larbin的URL去重用的很高效的bloom filter算法: 2. ...

  6. Python多线程爬虫爬取网页图片

    临近期末考试,但是根本不想复习!啊啊啊啊啊啊啊!!!! 于是做了一个爬虫,网址为 https://yande.re,网页图片为动漫美图(图片带点颜色........宅男福利 github项目地址为:h ...

  7. Python多线程爬虫详解

    一.程序进程和线程之间的关系 程序:一个应用就是一个程序,比如:qq,爬虫 进程:程序运行的资源分配最小单位, 很多人学习python,不知道从何学起.很多人学习python,掌握了基本语法过后,不知 ...

  8. python 多线程爬虫 实例

    多进程 Multiprocessing 模块 Process 类用来描述一个进程对象.创建子进程的时候,只需要传入一个执行函数和函数的参数即可完成 Process 示例的创建. star() 方法启动 ...

  9. python多线程爬虫:亚马逊价格

    import re import requests import threading import time from time import ctime,sleep from queue impor ...

随机推荐

  1. JSP FreeMarker Velocity 原理

    JSP原理 JSP的运行原理:JSP 本质上是一个Servlet. 每个JSP 页面在第一次被访问时,JSP引擎将它翻译成一个Servlet 程序,然后再把这个 Servlet 源程序编译成Servl ...

  2. 和風いろはちゃんイージー / Iroha and Haiku (ABC Edition) (水水)

    题目链接:http://abc042.contest.atcoder.jp/tasks/abc042_a Time limit : 2sec / Memory limit : 256MB Score ...

  3. nfs共享文件搭建

    Linux NFS服务器的安装与配置详解 一.NFS服务简介  NFS是Network  File System(网络文件系统).主要功能是通过网络让不同的服务器之间可以共享文件或者目录.NFS客户端 ...

  4. java基础之包装类型

    包装类型引入该类型的原因:      因为基本数据类型不具备对象的特性,不能调用方法,所以有时需要将其转换为包装类. 包装类型有两大类方法:      1.将本类型和其它基本类型进行转换方法.    ...

  5. mybatis的dao的mapper写法

    ## MyBatis的Dao编写[mapper代理方式实现] step1: 写一个接口,并写抽象方法 package com.sjl.mapper; import com.sjl.model.User ...

  6. Golang字符串函数认识(一)

    package main import ( "fmt" "strings" "strconv" ) func main(){ //返回字符串 ...

  7. BeautifulSoup 模块详解

    BeautifulSoup 模块详解 BeautifulSoup是一个模块,该模块用于接收一个HTML或XML字符串,然后将其进行格式化,之后遍可以使用他提供的方法进行快速查找指定元素,从而使得在HT ...

  8. 02: docker高级篇

    1.1 Docker Compose 1.Docker Compose 介绍 1. Compose是一个定义和管理多容器的工具,使用Python语言编写. 2. 使用Compose配置文件描述多个容器 ...

  9. JavaScript中冒泡与事件委托

    冒泡 事件触发后事件流的三个阶段按顺序依次是: 1.捕获阶段 2.目标阶段 3.冒泡阶段 大盒子包裹小盒子,两个盒子都分别添加点击事件,当点击小盒子,两个盒子的事件都会触发. 事件委托 下级元素委托上 ...

  10. Codeforces 841D Leha and another game about graph - 差分

    Leha plays a computer game, where is on each level is given a connected graph with n vertices and m  ...