Python爬虫之多线程下载程序类电子书

  近段时间,笔者发现一个神奇的网站:http://www.allitebooks.com/ ,该网站提供了大量免费的编程方面的电子书,是技术爱好者们的福音。其页面如下:

image

  那么我们是否可以通过Python来制作爬虫来帮助我们实现自动下载这些电子书呢?答案是yes.
  笔者在空闲时间写了一个爬虫,主要利用urllib.request.urlretrieve()函数和多线程来下载这些电子书。
  首先呢,笔者的想法是先将这些电子书的下载链接网址储存到本地的txt文件中,便于永久使用。其Python代码(Ebooks_spider.py)如下, 该代码仅下载第一页的10本电子书作为示例:

# -*- coding:utf-8 -*-
# 本爬虫用来下载http://www.allitebooks.com/中的电子书
# 本爬虫将需要下载的书的链接写入txt文件,便于永久使用
# 网站http://www.allitebooks.com/提供编程方面的电子书

#  导入必要的模块
import urllib.request
from bs4 import BeautifulSoup

#  获取网页的源代码
def get_content(url):
    html = urllib.request.urlopen(url)
    content = html.read().decode('utf-8')
    html.close()
    return content

# 将762个网页的网址储存在list中
base_url = 'http://www.allitebooks.com/'
urls = [base_url]
for i in range(2, 762):
    urls.append(base_url + 'page/%d/' % i)

# 电子书列表,每一个元素储存每本书的下载地址和书名
book_list =[]

# 控制urls的数量,避免书下载过多导致空间不够!!!
# 本例只下载前3页的电子书作为演示
# 读者可以通过修改url[:3]中的数字,爬取自己想要的网页书,最大值为762
for url in urls[:1]:
    try:
        # 获取每一页书的链接
        content = get_content(url)
        soup = BeautifulSoup(content, 'lxml')
        book_links = soup.find_all('div', class_="entry-thumbnail hover-thumb")
        book_links = [item('a')[0]['href'] for item in book_links]
        print('\nGet page %d successfully!' % (urls.index(url) + 1))
    except Exception:
        book_links = []
        print('\nGet page %d failed!' % (urls.index(url) + 1))

    # 如果每一页书的链接获取成功
    if len(book_links):
        for book_link in book_links:
            # 下载每一页中的电子书
            try:
                content = get_content(book_link)
                soup = BeautifulSoup(content, 'lxml')
                # 获取每本书的下载网址
                link = soup.find('span', class_='download-links')
                book_url = link('a')[0]['href']

                # 如果书的下载链接获取成功
                if book_url:
                    # 获取书名
                    book_name = book_url.split('/')[-1]
                    print('Getting book: %s' % book_name)
                    book_list.append(book_url)
            except Exception as e:
                print('Get page %d Book %d failed'
                      % (urls.index(url) + 1, book_links.index(book_link)))

# 文件夹
directory = 'E:\\Ebooks\\'
# 将书名和链接写入txt文件中,便于永久使用
with open(directory+'book.txt', 'w') as f:
    for item in book_list:
        f.write(str(item)+'\n')

print('写入txt文件完毕!')

可以看到,上述代码主要爬取的是静态页面,因此效率非常高!运行该程序,显示结果如下:

image

在book.txt文件中储存了这10本电子书的下载地址,如下:

image

  接着我们再读取这些下载链接,用urllib.request.urlretrieve()函数和多线程来下载这些电子书。其Python代码(download_ebook.py)如下:

# -*- coding:utf-8 -*-
# 本爬虫读取已写入txt文件中的电子书的链接,并用多线程下载

import time
from concurrent.futures import ThreadPoolExecutor, wait, ALL_COMPLETED
import urllib.request

# 利用urllib.request.urlretrieve()下载PDF文件
def download(url):
    # 书名
    book_name = 'E:\\Ebooks\\'+url.split('/')[-1]
    print('Downloading book: %s'%book_name) # 开始下载
    urllib.request.urlretrieve(url, book_name)
    print('Finish downloading book: %s'%book_name) #完成下载

def main():
    start_time = time.time() # 开始时间

    file_path = 'E:\\Ebooks\\book.txt' # txt文件路径
    # 读取txt文件内容,即电子书的链接
    with open(file_path, 'r') as f:
        urls = f.readlines()
    urls = [_.strip() for _ in urls]

    # 利用Python的多线程进行电子书下载
    # 多线程完成后,进入后面的操作
    executor = ThreadPoolExecutor(len(urls))
    future_tasks = [executor.submit(download, url) for url in urls]
    wait(future_tasks, return_when=ALL_COMPLETED)

    # 统计所用时间
    end_time = time.time()
    print('Total cost time:%s'%(end_time - start_time))

main()

运行上述代码,结果如下:

image

再去文件夹中查看文件:

image

可以看到这10本书都已成功下载,总共用时327秒,每本书的平均下载时间为32.7,约半分钟,而这些书的大小为87.7MB,可见效率相当高的!
  怎么样,看到爬虫能做这些多有意思的事情,不知此刻的你有没有心动呢?心动不如行动,至理名言~~
  本次代码已上传github, 地址为: https://github.com/percent4/Examples-of-Python-Spiders .

注意:本人现已开通两个微信公众号: 用Python做数学(微信号为:python_math)以及轻松学会Python爬虫(微信号为:easy_web_scrape), 欢迎大家关注哦~~

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,242评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,769评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,484评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,133评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,007评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,080评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,496评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,190评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,464评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,549评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,330评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,205评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,567评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,889评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,160评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,475评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,650评论 2 335

推荐阅读更多精彩内容