最近在学 Python,个人觉得 Python 是一种比较好玩的编程语言。快速看过一遍之后准备自己写个小说爬虫来巩固下 Python 基础知识。本人编程刚入门,很多东西理解还比较浅,写下来是为了作为笔记方便以后回来优化改进,如果对本篇文章有好的建议或者有不足的地方,欢迎各位指出。


目录

  • 目录
  • 1. 前期知识准备
  • 2. 选择爬取的目标
  • 3. 实操
    • 3.1 下载目标 url 的 html
    • 3.2 获取每一章的标题和正文
    • 3.3 保存标题和正文
    • 3.4 获取下一章的 url
    • 3.5 编写启动的方法
    • 3.6 启动爬虫
    • 3.7 附上完整代码
  • 4. 优化

1. 前期知识准备

Python 基础语法、正则表达式、BeautifulSoup 库
传送门:
廖雪峰老师的Python新手教程
BeautifulSoup教程,转自:http://www.cnblogs.com/wupeiqi/articles/6283017.html


2. 选择爬取的目标

我选取的目标是网上随便找的一个免费小说网:https://www.qu.la(其实是一个盗版小说网站)。选取这个网站的原因是该网站的 html 标签比较容易提取,适合练手,而且亲测没有任何反爬虫机制,可以随便蹂躏(咳咳,大家收敛一点,不要太用力)。坏处么…就是网站服务器不稳定,经常爬着爬着中断了,报10053错误,找不到原因只能重来,据说换成 Python 3不会出现这个问题?博主用的Python 2.7,还没试过Python 3,有时间的童鞋可以试一下。


3. 实操

下面进入正题,很激动有木有!博主仿佛看见小说网仿佛像一个柔弱无助的小姑娘躲在墙角瑟瑟发抖,嘿嘿嘿…
古人云:“机会总是留给有准备的人的。”所以我们要先理清好我们的思路,再动手,博主的思路如下:

Created with Raphaël 2.1.2开始下载目标url的html获取章节标题获取正文内容保存标题和正文确认是否有下一章?获取下一章url结束yesno

3.1 下载目标 url 的 html

我选取了《超级神基因》作为要下载的小说进行演示。定义一个download方法,传入两个参数。 url 为小说的第一章的网址:https://www.qu.la/book/25877/8923073.html,当网络出现错误时,重新发起请求,num_retries = 5默认同一链接请求不超过5次。该方法返回了网站的html代码。Python 代码如下:

import urllib2def download(url, num_retries=5):""":param url: the fist chapter's url of novel like 'https://www.qu.la/book/25877/8923073.html':param num_retries: times to retry to reconnect when fail to connect:return:html of url which be inputted"""print 'Start downloading:', urltry:html = urllib2.urlopen(url).read()print 'Download finished:', urlexcept urllib2.URLError as e:print 'Download fail.Download error:', e.reasonhtml = Noneif num_retries > 0:print 'Retrying:', urlhtml = download(url, num_retries - 1)return html

3.2 获取每一章的标题和正文

这一步我们要查看包含有标题和正文的标签,将相关的标签内容筛选出来。注意一定要将html代码下载下来再查看,不要直接用浏览器的开发工具查看源代码。博主踩了这个坑,发现一直匹配不到相关的标签,后来有前端老司机告诉我JavaScript代码可能会自动完成代码(好像是这么个意思,博主前端 0 基础),你在浏览器看到的代码很可能改变了。
将下载下来的html代码保存为一个.html文件,保存html代码如下:

import re
import oshtml = download('https://www.qu.la/book/25877/8923072.html')
with open(os.path.join(r'C:\Users\admin\Desktop', '123.html'), 'wb') as f:f.write(html)

查看保存的在桌面的123.html文件,可以发现章节标题的标签为<h1>

使用正则表达式在html代码中匹配该标签的内容,代码如下:

import redef get_title(html):"""Find Title of each chapter,return the title of chapter"""title_regex = re.compile('<h1>(.*?)</h1>', re.IGNORECASE)title = str(title_regex.findall(html)[0])return title

同理,在html代码中查找文本的相关标签为<div id="content">

然后这里有个坑,用正则表达式居然匹配不到!!!博主一脸懵逼地研究了几个小时未果,于是用了另一种方法:使用BeautifulSoup库。话不多说,放代码:

from bs4 import BeautifulSoupdef get_content(html):"""get content of each chapter from the html"""soup = BeautifulSoup(html, 'html.parser')# fixed_html = soup.prettify()div = soup.find('div', attrs={'id': 'content'})[s.extract() for s in soup('script')]# print divcontent = str(div).replace('<br/>', '\n').replace('<div id="content">', '').replace('</div>', '').strip()return content

3.3 保存标题和正文

接下来就是把上一步得到的标题和正文保存到文档中去,博主偷懒把地址写死了,这一步比较简单,不多做解释,看代码:

import redef save(title, content):with open(r'C:\Users\admin\Desktop\DNAofSuperGod\novel.txt', 'a+') as f:f.writelines(title + '\n')f.writelines(content + '\n')

3.4 获取下一章的 url

html代码中找到下一章的链接:

老规矩,在html代码中匹配这个标签,拿到href的内容,代码如下:

from bs4 import BeautifulSoupdef get_linkofnextchapter(html):"""This method will get the url of next chapter:return: a relative link of the next chapter"""soup = BeautifulSoup(html, 'html.parser')a = soup.find('a', attrs={'class': 'next', 'id': 'A3', 'target': '_top'})# print a['href']return a['href']

3.5 编写启动的方法

调用前面的方法,作为整个程序的入口,代码如下:

def begin(url):# make sure panth exitedif not os.path.isdir(r'C:\Users\admin\Desktop\DNAofSuperGod'):os.mkdir(r'C:\Users\admin\Desktop\DNAofSuperGod')# remove old file and build a new oneif os.path.isfile(r'C:\Users\admin\Desktop\DNAofSuperGod\novel.txt'):os.remove(r'C:\Users\admin\Desktop\DNAofSuperGod\novel.txt')html = download(url)# if html is None,download fail.if not html == None:title = get_title(html)print titlecontent = get_content(html)save(title, content)print 'Have saved %s for you.' % titlelink = get_linkofnextchapter(html)# judge if has next chapter?if not re.match(r'./', link):nexturl = urlparse.urljoin(url, link)begin(nexturl)else:print 'Save finished!'else:print 'Download fail'

3.6 启动爬虫

终于到达最后一步啦,我们要启动我们的爬虫程序,调用代码很简单:

url = 'https://www.qu.la/book/25877/8923072.html'
begin(url)

但是!如果顺利的话,在程序下载到900多章的时候,你可以很幸福地看到程序报错了!
下面这段是我复制的(我才不会傻傻的重新跑一遍程序呢)

RuntimeError: maximum recursion depth exceeded

找了度娘后发现这是python的保护机制,防止无限递归导致内存溢出,默认的递归深度是 1000,所以我们可以把这个默认值改大一点即可。

import sys# change recursion depth as 10000(defult is 1000)
sys.setrecursionlimit(10000)
url = 'https://www.qu.la/book/25877/8923072.html'
begin(url)

3.7 附上完整代码

import urllib2
import re
import os
import urlparseimport sys
from bs4 import BeautifulSoup# __author__:chenyuepeng"""
This demon is a webspider to get a novel from https://www.qu.la
"""def download(url, num_retries=5):""":param url: the fist chapter's url of novel like 'https://www.qu.la/book/25877/8923073.html':param num_retries: times to retry to reconnect when fail to connect:return:html of url which be inputted"""print 'Start downloading:', urltry:html = urllib2.urlopen(url).read()print 'Download finished:', urlexcept urllib2.URLError as e:print 'Download fail.Download error:', e.reasonhtml = Noneif num_retries > 0:print 'Retrying:', urlhtml = download(url, num_retries - 1)return htmldef get_title(html):"""Find Title of each chapter,return the title of chapter"""title_regex = re.compile('<h1>(.*?)</h1>', re.IGNORECASE)title = str(title_regex.findall(html)[0])return titledef get_content(html):"""get content of each chapter from the html"""soup = BeautifulSoup(html, 'html.parser')# fixed_html = soup.prettify()div = soup.find('div', attrs={'id': 'content'})[s.extract() for s in soup('script')]# print divcontent = str(div).replace('<br/>', '\n').replace('<div id="content">', '').replace('</div>', '').strip()return contentdef get_linkofnextchapter(html):"""This method will get the url of next chapter:return: a relative link of the next chapter"""soup = BeautifulSoup(html, 'html.parser')a = soup.find('a', attrs={'class': 'next', 'id': 'A3', 'target': '_top'})# print a['href']return a['href']def save(title, content):with open(r'C:\Users\admin\Desktop\DNAofSuperGod\novel.txt', 'a+') as f:f.writelines(title + '\n')f.writelines(content + '\n')def begin(url):# make sure panth exitedif not os.path.isdir(r'C:\Users\admin\Desktop\DNAofSuperGod'):os.mkdir(r'C:\Users\admin\Desktop\DNAofSuperGod')# remove old file and build a new oneif os.path.isfile(r'C:\Users\admin\Desktop\DNAofSuperGod\novel.txt'):os.remove(r'C:\Users\admin\Desktop\DNAofSuperGod\novel.txt')html = download(url)# if html is None,download fail.if not html == None:title = get_title(html)print titlecontent = get_content(html)save(title, content)print 'Have saved %s for you.' % titlelink = get_linkofnextchapter(html)# judge if has next chapter?if not re.match(r'./', link):nexturl = urlparse.urljoin(url, link)begin(nexturl)else:print 'Save finished!'else:print 'Download fail'# change recursion depth as 10000(defult is 900+)
sys.setrecursionlimit(10000)
url = 'https://www.qu.la/book/25877/8923072.html'
begin(url)

4. 优化

这是在初学Python后的练手项目,还有很多优化的空间,暂时先写下来,留待以后改进。如果有好的建议或者相关的问题,欢迎在评论区留言讨论。

  • 将单线程改为多线程或多进程,利用并发加快下载速度
  • 加入缓存机制,将下载过的url缓存到本地,如果程序中断了不需要从头开始下载,从缓存中提取相关信息即可

Python 实现一个自动下载小说的简易爬虫相关推荐

  1. 用Python写一个自动下载视频、弹幕、评论的软件(2022最新)

    文章目录 序言 效果展示 下载视频 下载弹幕 下载评论 软件生成 打包 序言 哈喽兄弟们,今天来实现一个Python采集视频.弹幕.评论与一体的小软件. 平常咱们都是直接代码运行,不过今天我们做成软件 ...

  2. 当我尝试写一个自动写小说的AI,长路漫漫的踩坑之路 ToT

    起因 事情是这样的,前几天我在刷B站的时候看到一个大佬用训练了一个自动写高考作文的AI 链接: https://www.bilibili.com/video/BV1pr4y1w7uM 那我就想既然别人 ...

  3. 使用Python设计一个自动查询文件夹的exe文件

    使用Python设计一个自动查询文件夹的exe文件 文章目录 使用Python设计一个自动查询文件夹的exe文件 前言 一.消灭噩梦(~~摸鱼~~ )的开始 二.~~摸鱼~~ 效果升级--添加拷贝功能 ...

  4. Python 小把戏之下载小说

    Python 小把戏之下载小说 #! /usr/bin/python3 # -*- coding: utf-8 -*- from bs4 import BeautifulSoup import sys ...

  5. python编写木马攻击_用Python写一个自动木马程序

    电脑作为大家日常办公的工具,最怕的一件事情之一就是被偷,当我们的电脑被盗的时候,不仅仅是电脑本身,更重要的是电脑存储的资料都会丢失.如何尽快的找回电脑需要我们想点办法,今天就教大家一个好的技巧,虽说不 ...

  6. python 通达信自动下载收盘和财务数据

    python 通达信自动下载收盘和财务数据,自动启动通达信,鼠标自动操作: 通达信直接从官网下载免费版,可下载财务数据. 自动识别屏幕尺寸(目前为1440x900.1920x1080.1366*768 ...

  7. python批量下载文件只有1kb_详解如何用python实现一个简单下载器的服务端和客户端...

    话不多说,先看代码: 客户端: import socket def main(): #creat: download_client=socket.socket(socket.AF_INET,socke ...

  8. 用python写一个自动群发微信脚本

    使用 Python 写一个自动群发微信脚本需要使用微信第三方 API 来实现.推荐使用 itchat 库,它提供了简单易用的 API,可以方便地编写微信自动化脚本. 首先,你需要安装 itchat 库 ...

  9. 用python做一个自动签到程序

    背景:疫情期间,学校要求每天在上午10点之前填报信息.有时容易忘记填报,就会受辅导员惩罚. 我们用"i至诚"填报,所以这里用这个例子来图文演示如何实现自动签到功能. 程序中使用到的 ...

  10. 发帖机python_如何用python写一个自动顶帖机?

    周末去了好朋友家玩,继上次我帮他修好电脑(插拔内存条+用橡皮擦擦金手指)后. 又问我说,小x啊,你是搞计算机的,能不能帮我写个自动顶帖(回复)的机器啊? 我的好朋友现在除了用两套房子收租外,觉得待在家 ...

最新文章

  1. Android:如何将Enum放入捆绑包中?
  2. 93. Leetcode 64. 最小路径和 (动态规划-路径规划)
  3. mapreduce编程实例(2)-求最大值和最小值
  4. 组词组合 php,PHP组词算法实现详解
  5. 纯js实现人脸识别眨眨眼张张嘴案例——alive_face.js
  6. Codeforces 138C(区间更新+离散化)
  7. codeforces B. Friends and Presents(二分+容斥)
  8. python—os模块、时间模块
  9. 文本框 价格 保留两位小数 讨论
  10. jeecms 代码生成 Tools
  11. 平衡二叉树(AVL树)和红黑树区别
  12. 前端项目如何做测试?
  13. NTC热敏电阻阻值-温度对照表
  14. tp5模板使用php函数,tp5模板变量使用自定义函数
  15. 2021-07-15-2021年全球10大最佳单板计算机开发板(SBC)(第1-3名)
  16. 实验吧——WEB-天下武功唯快不破
  17. 淘宝数据分析实战篇(附源码)
  18. php apm,apm是什么?
  19. ng-alain php,Angular 中后台前端解决方案 - Ng Alain 介绍
  20. 首届中国移动互联网直播行业峰会在京召开

热门文章

  1. [书目20110904]谢孟媛英文文法
  2. vb远程访问dde服务器,做wincc与VB的dde连接一定要用ddeserver吗?
  3. 关于修复msvcp110.dll丢失的问题
  4. 解决only integer scalar arrays can be converted to a scalar index
  5. 唐魏巍,天冷了,你妈妈叫你回家加衣服
  6. 干货|TPM管理系列之六源改善
  7. 瞳孔中的视觉刺激提取大脑中ERD/ERS
  8. 微软通过云存储插件简化Docker容器迁移
  9. 淘宝客?CPS技术是怎么实现的?
  10. 锆石FPGA---verlog语法篇