用 Python 爬取小说

Python 爬取网络的内容是非常方便的,但是在使用之前,要有一些前端的知识,比如: HTML、 CSS、XPath 等知识,再会一点点 Python 的内容就可以了。

因为使用的是 Anaconda ,所以大多数的包都已经有了,但是在使用过程中也有一些小问题,但是最终程序是实现了的。

  • BeautifulSoup 是一个可以从HTML或XML文件中提取数据的Python库。非常好用,具体的 文档可以从这里跳转 ,利用这篇文章可以让你轻松的进行网页的解析。可以把仅有的一点前端知识也略去了。
  • requests 适合正常人类使用的一个 HTTP 解析工具
  • time 让网站以为你不是电脑
  • sys 显示和刷新

代码:

# _*_ coding:UTF-8 _*_
from bs4 import BeautifulSoup
import requests
import time
import sys
"""
download 《武动乾坤》 from www.biqukan.com
Parameters:
    None
Returns:
    None
"""


class downloader(object):
    def __init__(self):
        self.server = "http://www.biqukan.com"
        self.target = "http://www.biqukan.com/3_3012"
        self.names = []
        self.urls = []
        self.nums = 0
    """
    To get Urls for download
    """

    def get_download_url(self):
        req = requests.get(url=self.target)
        html = req.text
        div_bf = BeautifulSoup(html, "html.parser")
        div = div_bf.find_all("div", class_="listmain")
        a_bf = BeautifulSoup(str(div[0]), "html.parser")
        a = a_bf.find_all("a")
        self.nums = len(a[12:])
        with open('武动乾坤目录.txt', 'a', encoding='utf-8') as f:
            for each in a[12:]:
                f.write(each.string)
                self.names.append(each.string)
                f.write(self.server + each.get("href"))
                self.urls.append(self.server + each.get("href"))
    """
    To get content
    Parameters:
        target - 下载链接
    Returns:
        content - 章节内容
    """

    def get_contents(self, target):
        headers = requests.utils.default_headers()
        headers['User-Agent'] = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.13; rv:61.0) Gecko/20100101 Firefox/61.0'
        req = requests.get(url=target, headers=headers)
        html = req.text
        bf = BeautifulSoup(html, "html.parser")
        texts = bf.find_all("div", class_="showtxt")
        content = texts[0].text.replace('\xa0' * 8, '\n\n')
        return content
    """
    To save to text
    Parameters:
        name - 章节名称
        path - 当前路径 + 小说名
        text - 章节内容
    Returns:
        None
    """

    def writer(self, name, path, text):
       # writer_flag = True
        with open(path, 'a', encoding='utf-8') as f:
            f.write(name + '\n')
            f.writelines(text)
            f.write('\n\n')


if __name__ == "__main__":
    dl = downloader()
    dl.get_download_url()
    print("第", dl.nums, "章")
    print("开始下载:")
    for i in range(dl.nums):
        time.sleep(1)
        dl.writer(dl.names[i], '武动乾坤.txt', dl.get_contents(dl.urls[i]))
        sys.stdout.write("  已下载:%.3f%%" % float(i/dl.nums*100) + '\r')
        sys.stdout.flush()
    print("下载完成")

几个小点需要注意:

  1. 不能访问的过快,所以在循环中进行一次等待,我这里用的是 time.sleep(1)
  2. 为了不被反爬虫识别为爬虫,需要在访问的时候,增加一个 header ,利用 headers = requests.utils.default_headers()headers['User-Agent'] = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.13; rv:61.0) Gecko/20100101 Firefox/61.0' 两行,就可以不被识别了
  3. 解析的时候,出现了一个问题,就是一开始从目录页获取的时候,只能读取 193 篇文章,经过排查,发现是在使用 BeautifulSoup 的时候解析的有点问题,将原本的 "lxml" 方式修改为"html.parser" 方式就可以了

不过因为这本小说字数真的有点多,所以下载过程有点慢,不过整体来说还是可以使用的。

Author
Tags
总结(3) Emacs(2) org mode(4) 年度清单(2) 读书清单(2) 电影清单(2) 电视清单(2) Python(3) 学习计划(1) 子弹笔记(1) 手帐体系(1) 时间管理(1) 时间使用效率(1) 形意拳(1) 知识管理(1) 简历(1) 技能水平(1) 生活(1) 减法生活(1) 阅读(1) 阅读分组(1) org(1) docx(1) markdown(2) cmder(1) 图床(1) jsdelivr(1) github(1) 安卓系统(1) 手动更新手机系统(1) post link(1) post path(1) hexo(2) hugo(2) GitHub Pages(1) travis(1) 自动部署博客(1) presentation(1) gcc(1) g++(1) 默认表格(1) 复杂表格(1) multimd table(1) google adsense(1) evil(1) surround(1) librime(2) emacs-rime(1) liberime(1) dot(1) graphviz(1) use-sub-superscripts(1) ditaa(1) Evil Multiple cursors(1) turn evil mode off(1) modifier keys(1) keymap(1) super(1) hyper(1) install Emacs(1) Mac OS(1) keybinds(1) clocktable(1) coding system(1) image library(1) keybind(1) spacemacs(1) org babel(1) homebrew(1) dd(1) diskutil(1) tmux(1) xcode(1) xcrun(1) node-gyp(1) tar(1) tree(1) pacman(1) plantuml(1) find(1) grep(2) du(1) apt-get(1) apt(1) regex(1) wildcard(1) zsh(1) gdb(1) lsof(1) netstat(1) rebase(2) workflow(1) 工作流(1) .gitignore(1) postbuffer(1) hung up(1) merge(1) cache(1) reset(1) Git(1) command(1) submodule(1) GitHub Pull Request(1) pr(1) Matplotlib(1) beautifusoup(1) 下载小说(1) SOLID(1) Leetcode(2) 透视表(1) read_excel()(1) pandas(1) conda(1) django(1) markdown-deux(1) mysql(1) oracle(1) 模糊查询(1) logging level(1) reflex(1) Field(1) Maven(1) Selenium(1) 下拉框(1) select into(1) insert into select(1) CAST(1) CONVERT(1) timestamp(1) concat(1) concat_ws(1) group_concat(1) union(1) grant privileges(1) 重置 root 密码(1) 报错 10060(1) 清理连接数(1) create user(1) set password(1) exists(1) in(1) markdown-it(1) emoji(1) tasks(1) valine(1) Code 504(1) Hugo(1) theme(1) substring(1) indexOf(1) RegExp(1) 定位节点(1) 正则匹配(1) async(1) 异步请求(1) css(2) layui(1) 滚动条(1) JavaScript(1)