如何从古腾堡自动下载书籍

时间:2018-05-09 12:07:38

标签: python urllib

我正在尝试从" http://www.gutenberg.org/"下载图书。我想知道为什么我的代码什么都没有。

import requests
import re
import os
import urllib

def get_response(url):
    response = requests.get(url).text 
    return response

def get_content(html):
    reg = re.compile(r'(<span class="mw-headline".*?</span></h2><ul><li>.*</a></li></ul>)',re.S) 
    return re.findall(reg,html)


def get_book_url(response):
    reg = r'a href="(.*?)"'
    return re.findall(reg,response)

def get_book_name(response):
    reg = re.compile('>.*</a>')
    return re.findall(reg,response)


def download_book(book_url,path):
    path = ''.join(path.split())
    path = 'F:\\books\\{}.html'.format(path) #my local file path

    if not os.path.exists(path):
        urllib.request.urlretrieve(book_url,path)
        print('ok!!!')
    else:
        print('no!!!')

def get_url_name(start_url):
    content = get_content(get_response(start_url))
    for i in content:
        book_url = get_book_url(i)
        if book_url:
            book_name = get_book_name(i)
            try:
                download_book(book_url[0],book_name[0])
            except:
                continue

def main():
    get_url_name(start_url)

if __name__ == '__main__':
    start_url = 'http://www.gutenberg.org/wiki/Category:Classics_Bookshelf'
    main()

我已经运行了代码,什么也没得到,没有追溯。如何从网站上自动下载图书?

3 个答案:

答案 0 :(得分:2)

  

我已经运行了代码,什么也没得到,没有追溯。

好吧,如果download_book()中出现异常,你就不可能获得追溯,因为你明确地说明了它们:

        try:
            download_book(book_url[0],book_name[0])
        except:
            continue

所以你要做的第一件事就是至少打印错误:

        try:
            download_book(book_url[0],book_name[0])
        except exception as e:
            print("while downloading book {} : got error {}".format(book_url[0], e)
            continue

或者根本不捕捉异常(至少在你知道会发生什么以及如何处理它之前)。

  

我甚至不知道如何解决它

学习如何调试实际上比学习如何编写代码更重要。要获得一般性介绍,您需要read this first

对于更具特定于python的内容,以下是跟踪程序执行的几种方法:

1 /在重要的地方添加print()来电,检查你真正得到的东西

2 /在交互式python shell中导入你的模块并单独测试你的函数(当它们都不依赖于全局变量时这会更容易)

3 / use the builtin step debugger

现在您的代码存在一些明显的问题:

1 /你没有测试request.get()的结果 - 由于很多原因,HTTP请求可能会失败,而且你得到回复的事实并不意味着你得到了预期的响应(您也可能有400+或500+响应。

2 /你用regexps解析html。 DONT - 正则表达式无法可靠地处理html,您需要一个合适的HTML解析器(BeautifulSoup是网络报废的规范解决方案,因为它非常宽容)。你的一些正则表达式看起来也很错误(贪婪匹配所有等)。

答案 1 :(得分:1)

start_url未在main()

中定义

您需要使用全局变量。否则,更好(更干净)的方法是传入您正在使用的变量。无论如何,我预计会出现错误start_url is not defined

def main(start_url):
    get_url_name(start_url)

if __name__ == '__main__':
    start_url = 'http://www.gutenberg.org/wiki/Category:Classics_Bookshelf'
    main(start_url)

修改

没关系,问题出在这一行:content = get_content(get_response(start_url))

get_content()中的正则表达式似乎与任何内容都不匹配。我的建议是使用BeautifulSoup,from bs4 import BeautifulSoup。有关您为什么不应该使用正则表达式解析html的任何信息,请参阅此答案RegEx match open tags except XHTML self-contained tags

要求正则表达式解析任意HTML就像要求初学者编写操作系统

答案 2 :(得分:0)

正如其他人所说,你没有输出,因为你的正则表达式与任何东西都不匹配。初始网址返回的文字在</h2><ul>之间有换行符,请尝试此操作:

r'(<span class="mw-headline".*?</span></h2>\n<ul><li>.*</a></li></ul>)'

当你修复那个,你将面临另一个错误,我建议一些调试打印输出如下:

def get_url_name(start_url):
    content = get_content(get_response(start_url))
    for i in content:
        print('[DEBUG] Handling:', i)
        book_url = get_book_url(i)
        print('[DEBUG] book_url:', book_url)
        if book_url:
            book_name = get_book_name(i)
            try:
                print('[DEBUG] book_url[0]:', book_url[0])
                print('[DEBUG] book_name[0]:', book_name[0])
                download_book(book_url[0],book_name[0])
            except:
                continue