图虫网-写在前面

经历了一顿噼里啪啦的操作之后,终于我把博客写到了第10篇,后面,慢慢的会涉及到更多的爬虫模块,有人问scrapy 啥时候开始用,这个我预计要在30篇以后了吧,后面的套路依旧慢节奏的,所以莫着急了,100篇呢,预计4~5个月写完,常见的反反爬后面也会写的,还有fuck login类的内容。

图虫网-爬取图虫网

为什么要爬取这个网站,不知道哎~ 莫名奇妙的收到了,感觉图片质量不错,不是那些妖艳贱货 可以比的,所以就开始爬了,搜了一下网上有人也在爬,但是基本都是py2,py3的还没有人写,所以顺手写一篇吧。

起始页面

https://tuchong.com/explore/

这个页面中有很多的标签,每个标签下面都有很多图片,为了和谐,我选择了一个非常好的标签花卉 你可以选择其他的,甚至,你可以把所有的都爬取下来。

https://tuchong.com/tags/%E8%8A%B1%E5%8D%89/  # 花卉编码成了  %E8%8A%B1%E5%8D%89  这个无所谓

我们这次也玩点以前没写过的,使用python中的queue,也就是队列

下面是我从别人那顺来的一些解释,基本爬虫初期也就用到这么多

1. 初始化: class Queue.Queue(maxsize) FIFO 先进先出

2. 包中的常用方法:

    - queue.qsize() 返回队列的大小
- queue.empty() 如果队列为空,返回True,反之False
- queue.full() 如果队列满了,返回True,反之False
- queue.full 与 maxsize 大小对应
- queue.get([block[, timeout]])获取队列,timeout等待时间 3. 创建一个“队列”对象
import queue
myqueue = queue.Queue(maxsize = 10) 4. 将一个值放入队列中
myqueue.put(10) 5. 将一个值从队列中取出
myqueue.get()

开始编码

首先我们先实现主要方法的框架,我依旧是把一些核心的点,都写在注释上面

def main():
# 声明一个队列,使用循环在里面存入100个页码
page_queue = Queue(100)
for i in range(1,101):
page_queue.put(i) # 采集结果(等待下载的图片地址)
data_queue = Queue() # 记录线程的列表
thread_crawl = []
# 每次开启4个线程
craw_list = ['采集线程1号','采集线程2号','采集线程3号','采集线程4号']
for thread_name in craw_list:
c_thread = ThreadCrawl(thread_name, page_queue, data_queue)
c_thread.start()
thread_crawl.append(c_thread) # 等待page_queue队列为空,也就是等待之前的操作执行完毕
while not page_queue.empty():
pass if __name__ == '__main__':
main()

代码运行之后,成功启动了4个线程,然后等待线程结束,这个地方注意,你需要把 ThreadCrawl 类补充完整

class ThreadCrawl(threading.Thread):

    def __init__(self, thread_name, page_queue, data_queue):
# threading.Thread.__init__(self)
# 调用父类初始化方法
super(ThreadCrawl, self).__init__()
self.threadName = thread_name
self.page_queue = page_queue
self.data_queue = data_queue def run(self):
print(self.threadName + ' 启动************')

运行结果

线程已经开启,在run方法中,补充爬取数据的代码就好了,这个地方引入一个全局变量,用来标识爬取状态

CRAWL_EXIT = False

先在main方法中加入如下代码

CRAWL_EXIT = False  # 这个变量声明在这个位置
class ThreadCrawl(threading.Thread): def __init__(self, thread_name, page_queue, data_queue):
# threading.Thread.__init__(self)
# 调用父类初始化方法
super(ThreadCrawl, self).__init__()
self.threadName = thread_name
self.page_queue = page_queue
self.data_queue = data_queue def run(self):
print(self.threadName + ' 启动************')
while not CRAWL_EXIT:
try:
global tag, url, headers,img_format # 把全局的值拿过来
# 队列为空 产生异常
page = self.page_queue.get(block=False) # 从里面获取值
spider_url = url_format.format(tag,page,100) # 拼接要爬取的URL
print(spider_url)
except:
break timeout = 4 # 合格地方是尝试获取3次,3次都失败,就跳出
while timeout > 0:
timeout -= 1
try:
with requests.Session() as s:
response = s.get(spider_url, headers=headers, timeout=3)
json_data = response.json()
if json_data is not None:
imgs = json_data["postList"]
for i in imgs:
imgs = i["images"]
for img in imgs:
img = img_format.format(img["user_id"],img["img_id"])
self.data_queue.put(img) # 捕获到图片链接,之后,存入一个新的队列里面,等待下一步的操作 break except Exception as e:
print(e) if timeout <= 0:
print('time out!')
def main():
# 代码在上面 # 等待page_queue队列为空,也就是等待之前的操作执行完毕
while not page_queue.empty():
pass # 如果page_queue为空,采集线程退出循环
global CRAWL_EXIT
CRAWL_EXIT = True # 测试一下队列里面是否有值
print(data_queue)

经过测试,data_queue 里面有数据啦!!,哈哈,下面在使用相同的操作,去下载图片就好喽



完善main方法

def main():
# 代码在上面 for thread in thread_crawl:
thread.join()
print("抓取线程结束") thread_image = []
image_list = ['下载线程1号', '下载线程2号', '下载线程3号', '下载线程4号']
for thread_name in image_list:
Ithread = ThreadDown(thread_name, data_queue)
Ithread.start()
thread_image.append(Ithread) while not data_queue.empty():
pass global DOWN_EXIT
DOWN_EXIT = True for thread in thread_image:
thread.join()
print("下载线程结束")

还是补充一个 ThreadDown 类,这个类就是用来下载图片的。


class ThreadDown(threading.Thread):
def __init__(self, thread_name, data_queue):
super(ThreadDown, self).__init__()
self.thread_name = thread_name
self.data_queue = data_queue def run(self):
print(self.thread_name + ' 启动************')
while not DOWN_EXIT:
try:
img_link = self.data_queue.get(block=False)
self.write_image(img_link)
except Exception as e:
pass def write_image(self, url): with requests.Session() as s:
response = s.get(url, timeout=3)
img = response.content # 获取二进制流 try:
file = open('image/' + str(time.time())+'.jpg', 'wb')
file.write(img)
file.close()
print('image/' + str(time.time())+'.jpg 图片下载完毕') except Exception as e:
print(e)
return

运行之后,等待图片下载就可以啦~~



关键注释已经添加到代码里面了,收图吧 (◕ᴗ◕✿),这次代码回头在上传到github上 因为比较简单



当你把上面的花卉修改成比如xx啥的~,就是天外飞仙

Python爬虫入门教程 10-100 图虫网多线程爬取的更多相关文章

  1. Python爬虫入门教程第七讲: 蜂鸟网图片爬取之二

    蜂鸟网图片--简介 今天玩点新鲜的,使用一个新库 aiohttp ,利用它提高咱爬虫的爬取速度. 安装模块常规套路 pip install aiohttp 运行之后等待,安装完毕,想要深造,那么官方文 ...

  2. Python爬虫入门教程 15-100 石家庄政民互动数据爬取

    石家庄政民互动数据爬取-写在前面 今天,咱抓取一个网站,这个网站呢,涉及的内容就是 网友留言和回复,特别简单,但是网站是gov的.网址为 http://www.sjz.gov.cn/col/14900 ...

  3. Python爬虫入门教程 13-100 斗图啦表情包多线程爬取

    斗图啦表情包多线程爬取-写在前面 今天在CSDN博客,发现好多人写爬虫都在爬取一个叫做斗图啦的网站,里面很多表情包,然后瞅了瞅,各种实现方式都有,今天我给你实现一个多线程版本的.关键技术点 aioht ...

  4. Python爬虫入门教程 2-100 妹子图网站爬取

    妹子图网站爬取---前言 从今天开始就要撸起袖子,直接写Python爬虫了,学习语言最好的办法就是有目的的进行,所以,接下来我将用10+篇的博客,写爬图片这一件事情.希望可以做好. 为了写好爬虫,我们 ...

  5. Python爬虫入门教程 27-100 微医挂号网专家团队数据抓取pyspider

    1. 微医挂号网专家团队数据----写在前面 今天尝试使用一个新的爬虫库进行数据的爬取,这个库叫做pyspider,国人开发的,当然支持一下. github地址: https://github.com ...

  6. Python爬虫入门教程 24-100 微医挂号网医生数据抓取

    1. 写在前面 今天要抓取的一个网站叫做微医网站,地址为 https://www.guahao.com ,我们将通过python3爬虫抓取这个网址,然后数据存储到CSV里面,为后面的一些分析类的教程做 ...

  7. Python爬虫入门教程 19-100 51CTO学院IT技术课程抓取

    写在前面 从今天开始的几篇文章,我将就国内目前比较主流的一些在线学习平台数据进行抓取,如果时间充足的情况下,会对他们进行一些简单的分析,好了,平台大概有51CTO学院,CSDN学院,网易云课堂,慕课网 ...

  8. Python爬虫入门教程 23-100 石家庄链家租房数据抓取

    1. 写在前面 作为一个活跃在京津冀地区的开发者,要闲着没事就看看石家庄这个国际化大都市的一些数据,这篇博客爬取了链家网的租房信息,爬取到的数据在后面的博客中可以作为一些数据分析的素材. 我们需要爬取 ...

  9. Python爬虫入门教程 43-100 百思不得姐APP数据-手机APP爬虫部分

    1. Python爬虫入门教程 爬取背景 2019年1月10日深夜,打开了百思不得姐APP,想了一下是否可以爬呢?不自觉的安装到了夜神模拟器里面.这个APP还是比较有名和有意思的. 下面是百思不得姐的 ...

随机推荐

  1. Android 博客导航

    Android 博客导航 一. 基础知识 Android 常用知识点 Android 常见问题解决 Android 常用控件 控件常用属性 Material Design 常用控件 二.常用知识点 动 ...

  2. Run Keyword And Ignore Error,Run Keyword And Return Status,Run Keyword And Continue On Failure,Run Keyword And Expect Error,Wait Until Keyword Succeeds用法

    *** Test Cases ***case1 #即使错误也继续执行,也不记录失败,且可以返回执行状态和错误信息 ${Run Keyword And Ignore Error status} ${st ...

  3. C语言中数组使用负数值的标记

    ·引 对数组的认知 在c语言中,我们经常使用的一个结构便是数组,在最开始学习数组的时候,它被描述成这样(以一维二维数组为例):一维数组是若干个数连续排列在一起的集合,我们可以通过0-N的标记(N为数组 ...

  4. BZOJ2143: 飞飞侠

    2143: 飞飞侠 题意: 给出两个 n ∗ m 的矩阵 A,B,以及 3 个人的坐标 在 (i, j) 支付 Ai,j 的费用可以弹射到曼哈顿距离不超过 Bi,j 的位置 问三个人汇合所需要的最小总 ...

  5. [开源] C# 封装 银海医保的接口

    Github 地址: https://github.com/zifeiniu/YinHaiYiBaoCSharpAPI C#Model封装 银海医保的接口 介绍 银海医保的接口我就不说了,很多家医院在 ...

  6. python基础知识总结(一)

    学完python很久了,一直想着写个学习总结,奈何懒癌晚期,现在才开始写.以下是我总结的一小部分python基础知识点的总结: 1.什么是解释型语言?什么是编译型编程语言? ''' 解释型语言:无需编 ...

  7. MyBatis(10)使用association进行分步查询

    (1)接口中编写方法 public Emp getEmpByStep(Integer id); public Dept getDeptById(Integer id); (2)Mapper文件 < ...

  8. 最短路径问题—Dijkstra算法

    算法: import java.util.*; public class Main6 { public static int N = 1050; public static final int INF ...

  9. 【腾讯海纳】系统未发布时如何获取获取property_id在本地进行测试?

    有现成https协议域名使用者,可忽略此文. 直接先上图,明白的人看一眼图片就知道怎么拿了,如下所示: 解释说明: 在完成添加套件,以及测试应用的前提下,按如下操作流程: 1.访问路径:登录“海纳开发 ...

  10. Django model对象接口

    Django model查询 # 直接获取表对应字段的值,列表嵌元组形式返回 Entry.objects.values_list('id', 'headline') #<QuerySet [(1 ...