Python爬虫入门教程 14-100 All IT eBooks多线程爬取

简介: 1.All IT eBooks多线程-写在前面对一个爬虫爱好者来说,或多或少都有这么一点点的收集癖 ~ 发现好的图片,发现好的书籍,发现各种能存放在电脑上的东西,都喜欢把它批量的爬取下来。 然后放着,是的,就这么放着.......然后慢慢的遗忘掉.....All IT eBooks多线程-爬虫分析打开网址 http://www.allitebooks.com/ 发现特别清晰的小页面,一看就好爬在点击一本图书进入,发现下载的小链接也很明显的展示在了我们面前,小激动一把,这么清晰无广告的网站不多见了。

1.All IT eBooks多线程-写在前面

对一个爬虫爱好者来说,或多或少都有这么一点点的收集癖 ~ 发现好的图片,发现好的书籍,发现各种能存放在电脑上的东西,都喜欢把它批量的爬取下来。 然后放着,是的,就这么放着.......然后慢慢的遗忘掉.....

6af89bc8gw1f8sw1x8sumg205m05k74f

All IT eBooks多线程-爬虫分析

打开网址 http://www.allitebooks.com/ 发现特别清晰的小页面,一看就好爬
image

在点击一本图书进入,发现下载的小链接也很明显的展示在了我们面前,小激动一把,这么清晰无广告的网站不多见了。
image

All IT eBooks多线程-撸代码

这次我采用了一个新的模块 requests-html 这个模块的作者之前开发了一款 requests,你应该非常熟悉了,线程控制采用的 queue
安装 requests-html 模块


pip install requests-html

关于这个模块的使用,你只需要使用搜索引擎搜索一下这个模块名称,那文章也是很多滴,作为能学到这篇博客的你来说,是很简单的拉~

我们编写一下核心的内容

from requests_html import HTMLSession
from queue import Queue
import requests
import random

import threading
CARWL_EXIT = False
DOWN_EXIT = False

#####
# 其他代码
####
if __name__ == '__main__':

    page_queue = Queue(5)
    for i in range(1,6):
        page_queue.put(i)  # 把页码存储到page_queue里面

    # 采集结果
    data_queue = Queue()

    # 记录线程列表
    thread_crawl = []
    # 每次开启5个线程
    craw_list = ["采集线程1号","采集线程2号","采集线程3号","采集线程4号","采集线程5号"]

    for thread_name in craw_list:
        c_thread = ThreadCrawl(thread_name,page_queue,data_queue)
        c_thread.start()
        thread_crawl.append(c_thread)

    while not page_queue.empty():
        pass

    # 如果page_queue为空,采集线程退出循环
    CARWL_EXIT = True
    for thread in thread_crawl:
        thread.join()
        print("抓取线程结束")

上面就是爬取图书详情页面的线程了,我开启了5个线程爬取,页码也只爬取了5 页,如果你需要更多的,只需要修改

    page_queue = Queue(5)
    for i in range(1,6):
        page_queue.put(i)  # 把页码存储到page_queue里面

下面我们把 ThreadCrawl 类编写完毕

session = HTMLSession()

# 这个地方是 User_Agents 以后我把他配置到服务器上面,就可以远程获取了  这个列表里面有很多项,你自己去源码里面找吧
USER_AGENTS = [
    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_3) AppleWebKit/535.20 (KHTML, like Gecko) Chrome/19.0.1036.7 Safari/535.20"
]
# 获取图书下载链接的线程类
class ThreadCrawl(threading.Thread):
    # 构造函数
    def __init__(self,thread_name,page_queue,data_queue):

        super(ThreadCrawl,self).__init__()
        self.thread_name = thread_name
        self.page_queue = page_queue
        self.data_queue = data_queue
        self.page_url = "http://www.allitebooks.com/page/{}"   #URL拼接模板

    def run(self):
        print(self.thread_name+" 启动*********")

        while not CARWL_EXIT:
            try:
                page = self.page_queue.get(block=False)
                page_url = self.page_url.format(page)   # 拼接URL操作
                self.get_list(page_url)   # 分析页面链接 

            except Exception as e:
                print(e)
                break


    # 获取当前列表页所有图书链接
    def get_list(self,url):
        try:
            response = session.get(url)
        except Exception as e:
            print(e)
            raise e

        all_link = response.html.find('.entry-title>a') # 获取页面所有图书详情链接

        for link in all_link:
            self.get_book_url(link.attrs['href'])   # 获取图书链接

    # 获取图书下载链接
    def get_book_url(self,url):
        try:
            response = session.get(url)

        except Exception as e:
            print(e)
            raise e

        download_url = response.html.find('.download-links a', first=True)

        if download_url is not None: # 如果下载链接存在,那么继续下面的爬取工作
            link = download_url.attrs['href']
            self.data_queue.put(link)   # 把图书下载地址 存储到 data_queue里面,准备后面的下载
            print("抓取到{}".format(link))

上述代码一个非常重要的内容就是把图书的下载链接存储到了data_queue 里面,这些数据 在另一个下载线程里面是最基本的数据。

下面开始 编写图书下载的类和方法。

我开启了4个线程,操作和上面的非常类似

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:
                book_link = self.data_queue.get(block=False)
                self.download(book_link)
            except Exception as e:
                pass

    def download(self,url):
        # 随机浏览器User-Agent
        headers = {"User-Agent":random.choice(USER_AGENTS)}
        # 获取文件名字
        filename = url.split('/')[-1]
        # 如果url里面包含pdf
        if '.pdf' in url or '.epub' in url:
            file = 'book/'+filename  # 文件路径已经写死,请在跟目录先创建好一个book文件夹
            with open(file,'wb') as f:  # 开始二进制写文件
                print("正在下载 {}".format(filename))
                response = requests.get(url,stream=True,headers=headers)
                # 获取文件大小
                totle_length = response.headers.get("content-length")
                # 如果文件大小不存在,则直接写入返回的文本
                if totle_length is None:
                    f.write(response.content)
                else:
                    for data in response.iter_content(chunk_size=4096):
                        f.write(data)
                    else:
                        f.close()

                print("{}下载完成".format(filename))

if __name__ == '__main__': 

# 其他代码在上面
    thread_image = []
    image_list = ['下载线程1号', '下载线程2号', '下载线程3号', '下载线程4号']
    for thread_name in image_list:
        d_thread = ThreadDown(thread_name, data_queue)
        d_thread.start()
        thread_image.append(d_thread)

    while not data_queue.empty():
        pass

    DOWN_EXIT = True
    for thread in thread_image:
        thread.join()
        print("下载线程结束")

如果你把我上面的代码都组合完毕,那么应该可以很快速的去爬取图书了,当然这些图书都是英文了,下载下来你能不能读....... 我就不知道了。

image

相关文章
|
2月前
|
并行计算 安全 Java
Python GIL(全局解释器锁)机制对多线程性能影响的深度分析
在Python开发中,GIL(全局解释器锁)一直备受关注。本文基于CPython解释器,探讨GIL的技术本质及其对程序性能的影响。GIL确保同一时刻只有一个线程执行代码,以保护内存管理的安全性,但也限制了多线程并行计算的效率。文章分析了GIL的必要性、局限性,并介绍了多进程、异步编程等替代方案。尽管Python 3.13计划移除GIL,但该特性至少要到2028年才会默认禁用,因此理解GIL仍至关重要。
133 16
Python GIL(全局解释器锁)机制对多线程性能影响的深度分析
|
17天前
|
Python
python3多线程中使用线程睡眠
本文详细介绍了Python3多线程编程中使用线程睡眠的基本方法和应用场景。通过 `time.sleep()`函数,可以使线程暂停执行一段指定的时间,从而控制线程的执行节奏。通过实际示例演示了如何在多线程中使用线程睡眠来实现计数器和下载器功能。希望本文能帮助您更好地理解和应用Python多线程编程,提高程序的并发能力和执行效率。
42 20
|
12天前
|
数据采集 存储 数据挖掘
深入剖析 Python 爬虫:淘宝商品详情数据抓取
深入剖析 Python 爬虫:淘宝商品详情数据抓取
|
15天前
|
存储 数据采集 数据库
Python爬虫实战:股票分时数据抓取与存储
Python爬虫实战:股票分时数据抓取与存储
|
4天前
|
数据采集 Java 数据处理
Python实用技巧:轻松驾驭多线程与多进程,加速任务执行
在Python编程中,多线程和多进程是提升程序效率的关键工具。多线程适用于I/O密集型任务,如文件读写、网络请求;多进程则适合CPU密集型任务,如科学计算、图像处理。本文详细介绍这两种并发编程方式的基本用法及应用场景,并通过实例代码展示如何使用threading、multiprocessing模块及线程池、进程池来优化程序性能。结合实际案例,帮助读者掌握并发编程技巧,提高程序执行速度和资源利用率。
14 0
|
3月前
|
人工智能 数据可视化 数据挖掘
探索Python编程:从基础到高级
在这篇文章中,我们将一起深入探索Python编程的世界。无论你是初学者还是有经验的程序员,都可以从中获得新的知识和技能。我们将从Python的基础语法开始,然后逐步过渡到更复杂的主题,如面向对象编程、异常处理和模块使用。最后,我们将通过一些实际的代码示例,来展示如何应用这些知识解决实际问题。让我们一起开启Python编程的旅程吧!
|
3月前
|
存储 数据采集 人工智能
Python编程入门:从零基础到实战应用
本文是一篇面向初学者的Python编程教程,旨在帮助读者从零开始学习Python编程语言。文章首先介绍了Python的基本概念和特点,然后通过一个简单的例子展示了如何编写Python代码。接下来,文章详细介绍了Python的数据类型、变量、运算符、控制结构、函数等基本语法知识。最后,文章通过一个实战项目——制作一个简单的计算器程序,帮助读者巩固所学知识并提高编程技能。
|
3月前
|
Unix Linux 程序员
[oeasy]python053_学编程为什么从hello_world_开始
视频介绍了“Hello World”程序的由来及其在编程中的重要性。从贝尔实验室诞生的Unix系统和C语言说起,讲述了“Hello World”作为经典示例的起源和流传过程。文章还探讨了C语言对其他编程语言的影响,以及它在系统编程中的地位。最后总结了“Hello World”、print、小括号和双引号等编程概念的来源。
128 80
|
2月前
|
存储 缓存 Java
Python高性能编程:五种核心优化技术的原理与Python代码
Python在高性能应用场景中常因执行速度不及C、C++等编译型语言而受质疑,但通过合理利用标准库的优化特性,如`__slots__`机制、列表推导式、`@lru_cache`装饰器和生成器等,可以显著提升代码效率。本文详细介绍了这些实用的性能优化技术,帮助开发者在不牺牲代码质量的前提下提高程序性能。实验数据表明,这些优化方法能在内存使用和计算效率方面带来显著改进,适用于大规模数据处理、递归计算等场景。
73 5
Python高性能编程:五种核心优化技术的原理与Python代码
|
3月前
|
Python
[oeasy]python055_python编程_容易出现的问题_函数名的重新赋值_print_int
本文介绍了Python编程中容易出现的问题,特别是函数名、类名和模块名的重新赋值。通过具体示例展示了将内建函数(如`print`、`int`、`max`)或模块名(如`os`)重新赋值为其他类型后,会导致原有功能失效。例如,将`print`赋值为整数后,无法再用其输出内容;将`int`赋值为整数后,无法再进行类型转换。重新赋值后,这些名称失去了原有的功能,可能导致程序错误。总结指出,已有的函数名、类名和模块名不适合覆盖赋新值,否则会失去原有功能。如果需要使用类似的变量名,建议采用其他命名方式以避免冲突。
56 14

热门文章

最新文章