【Python】我的第一个完整的小说爬虫
写在开头
纪念我的第一个爬虫程序,一共写了三个白天,其中有两个上午没有看,中途遇到了各种奇怪的问题,伴随着他们的解决,对于一些基本的操作也弄清楚了。果然,对于这些东西的最号的学习方式,就是在使用中学习,通过解决问题的方式来搞定这些知识。按需索取,才能更有针对性。
大体记录下整个过程。
准备构思
出于对于python的热爱,想要尝试一些练手的项目,但是不论是看书,还是直接尝试别人的项目,到最后都会沦为不停地复制粘贴...最实际的就是自己来上手亲自写代码。思路都是一样的,但是具体的实现还得靠自己。
以前的复制粘贴给我的帮助也就是告诉了我大致的流程。
确定目标网址
目标网址是关键。我梦想中的爬虫是那种偏向于更智能的,直接给他一个想要获取的关键词,一步步的流程直接自己完成,可以自己给定范围,也可以直接爬取整个互联网或者更实际的就是整个百度上的内容,但是,目前就我而言,见到的爬虫,都是给定目标网址,通过目标页面上的内容进一步执行规定的操作,所以现在来看,我们在写爬虫之前,需要确定一个基准页面,这个是需要我们事先制定的。在考虑我们需要程序完成怎样的功能,获取页面文本还是相关链接内容还是其他的目的。
我这个程序想要获取的是《剑来》小说,把各个章节的内容爬去下载存储到文件里。
编程只是实现目的的工具。
所以重点是分析我们的需求。
获取小说目录页面是基本。这里有各个章节的链接,标题等等内容。这是我们需要的。
有了各个章节的链接,就需要进入其中获得各个章节的内容。
所以,我们需要获得页面内容,需要从中获得目标内容。
所以使用 urllib.request,re 库。
前者用来获得网页内容,后者获得目标信息。
headers
直接使用urllib.request的urlopen(),read()方法是会报类似以下的错误(这里是网上查找过来的,都是类似的):
raise HTTPError(req.get_full_url(), code, msg, hdrs, fp)
HTTPError: HTTP Error 403: Forbidden
出现urllib2.HTTPError: HTTP Error 403: Forbidden错误是由于网站禁止爬虫,可以在请求加上头信息,伪装成浏览器。
headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 6.3; Win64; x64; rv:55.0) Gecko/20100101 Firefox/55.0'}
request = url_req.Request(url, headers=headers)
response = url_req.urlopen(request, data=None, timeout=3)
html = response.read().decode('GBK')
注意:这里存在两个容易出问题的地方。
- 编码:编码问题是使用爬虫中有时候会很头痛的问题,由于网页源代码编码格式不明确,所以这里尝试了许久。
使用chardet库的detect()方法可以检测字节字符串的编码。所以直接检测这里的html(先不要解码)。输出的是GB2312,但是在后面页面的爬取中,会出现提示有的字符的编码异常,所以这里采取了比其范围更广的中文字符集GBK,解决了这个问题。
- 设置超时范围:由于频繁的获取网页内容,目标网站有时候会出现没有响应的问题。
(这个问题可以见我在CSDN上的提问:关于python爬虫程序中途停止的问题)
于是我采取了捕获 urlopen()的socket.timeout异常,并在出现异常的时候再循环访问,直到获得目标页面。
获得目标内容
这里使用的是正则表达式。re模块。这里的使用并不复杂。
首先需要一个模式字符串。以re.I指定忽略大小写,编译后的对象拥有本身匹配的方法,这里使用的是findall(),返回一个所有结果组成的列表。可以及时返回输出其内容,进而选择合适的部分进行处理。
通过查看相关的符号,这里使用(.+?)来实现匹配非贪婪模式(尽量少的)下任意无限字符,对之使用(),进而匹配括号内的模式。
文件写入
使用with open() as file:,进而可以处理文件。并且可以自动执行打开和关闭文件,更为便捷安全。
with open(findall_title[0] + '.txt', 'w+', encoding='utf-8') as open_file:
- 这里也要注意编码的问题,指定
utf-8。会避免一些问题。 - 这里使用
w+模式,追加写文件。
完整代码
# -*- coding: utf-8 -*-
"""
Created on Fri Aug 11 16:31:42 2017
@author: lart
"""
import urllib.request as url_req
import re, socket, time
def r_o_html(url):
print('r_o_html begin')
headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 6.3; Win64; x64; rv:55.0) Gecko/20100101 Firefox/55.0'}
request = url_req.Request(url, headers=headers)
NET_STATUS = False
while not NET_STATUS:
try:
response = url_req.urlopen(request, data=None, timeout=3)
html = response.read().decode('GBK')
print('NET_STATUS is good')
print('r_o_html end')
return html
except socket.timeout:
print('NET_STATUS is not good')
NET_STATUS = False
def re_findall(re_string, operation, html):
print('re_findall begin')
pattern = re.compile(re_string, re.I)
if operation == 'findall':
result = pattern.findall(html)
else:
print('this operation is invalid')
exit(-1)
print('re_findall end')
return result
if __name__ == '__main__':
url_base = 'http://www.7kankan.la/book/1/'
html = r_o_html(url_base)
findall_title = re_findall(r'<title>(.+?)</title>', 'findall', html)
findall_chapter = re_findall(r'<dd class="col-md-3"><a href=[\',"](.+?)[\',"] title=[\',"](.+?)[\',"]>', 'findall', html)
with open(findall_title[0] + '.txt', 'w+', encoding='utf-8') as open_file:
print('article文件打开', findall_chapter)
for i in range(len(findall_chapter)):
print('第' + str(i) + '章')
open_file.write('\n\n\t' + findall_chapter[i][1] + '\n --------------------------------------------------------------------- \n')
url_chapter = url_base + findall_chapter[i][0]
html_chapter = r_o_html(url_chapter)
findall_article = re_findall(r' (.+?)<br />', 'findall', html_chapter)
findall_article_next = findall_chapter[i][0].replace('.html', '_2.html')
url_nextchapter = url_base + findall_article_next
html_nextchapter = r_o_html(url_nextchapter)
if html_nextchapter:
findall_article.extend(re_findall(r' (.+?)<br />', 'findall', html_nextchapter))
for text in findall_article:
open_file.write(text + '\n')
time.sleep(1)
print('文件写入完毕')
【Python】我的第一个完整的小说爬虫的更多相关文章
- python入门学习之Python爬取最新笔趣阁小说
Python爬取新笔趣阁小说,并保存到TXT文件中 我写的这篇文章,是利用Python爬取小说编写的程序,这是我学习Python爬虫当中自己独立写的第一个程序,中途也遇到了一些困难,但是最后 ...
- 用Python编写的第一个回测程序
用Python编写的第一个回测程序 2016-08-06 def savfig(figureObj, fn_prefix1='backtest8', fn_prefix2='_1_'): import ...
- Python开发【第一篇】:目录
本系列博文包含 Python基础.前端开发.Web框架.缓存以及队列等,希望可以给正在学习编程的童鞋提供一点帮助!!! Python开发[第一篇]:目录 Python开发[第二篇]:初识Python ...
- Python自动化培训第一周学习总结
Python自动化培训第一周学习结束,看视频复习,把作业完成了. 总体来说,开卷有益. 首先,工具真是好东西,能够极大提升效率,也是人区别于动物所在.想起前任大领导对工具的不屑,本质也是对效率的不屑, ...
- Python开发【第一篇】:目录
本系列博文包含Python基础.前端开发.Web框架.缓存以及队列等,希望可以给正在学习Python编程的朋友们提供一点帮助! .Python开发[第一篇]:目录 .Python开发[第二篇]:初始P ...
- python测试mysql写入性能完整实例
这篇文章主要介绍了python测试mysql写入性能完整实例,具有一定借鉴价值,需要的朋友可以参考下 本文主要研究的是python测试mysql写入性能,分享了一则完整代码,具体介绍如下. 测试环境: ...
- 通过游戏学python 3.6 第一季 第九章 实例项目 猜数字游戏--核心代码--猜测次数--随机函数和屏蔽错误代码--优化代码及注释--简单账号密码登陆--账号的注册查询和密码的找回修改--锁定账号--锁定次数--菜单功能'menufile
通过游戏学python 3.6 第一季 第九章 实例项目 猜数字游戏--核心代码--猜测次数--随机函数和屏蔽错误代码--优化代码及注释--简单账号密码登陆--账号的注册查询和密码的找回修改--锁 ...
- 通过游戏学python 3.6 第一季 第八章 实例项目 猜数字游戏--核心代码--猜测次数--随机函数和屏蔽错误代码--优化代码及注释--简单账号密码登陆--账号的注册查询和密码的找回修改--锁定账号--锁定次数
通过游戏学python 3.6 第一季 第八章 实例项目 猜数字游戏--核心代码--猜测次数--随机函数和屏蔽错误代码--优化代码及注释--简单账号密码登陆--账号的注册查询和密码的找回修改--锁定账 ...
- 通过游戏学python 3.6 第一季 第二章 实例项目 猜数字游戏--核心代码--猜测次数 可复制直接使用 娱乐 可封装 函数
猜数字游戏--核心代码--猜测次数 #猜数字--核心代码--猜测次数 number=33 amount=3 count=0 while count<=amount: conversion ...
随机推荐
- nslookup 工具的使用方法记录
查询IP地址 nslookup最简单的用法就是查询域名对应的IP地址,包括A记录和CNAME记录,如果查到的是CNAME记录还会返回别名记录的设置情况.其用法是: nslookup 域名 定查询记录类 ...
- Codeforces 980 并查集/模拟贪心最小字典序 找规律/数去除完全平方因子 逆思维倍增预处理祖先标记点
A /*Huyyt*/ #include<bits/stdc++.h> #define mem(a,b) memset(a,b,sizeof(a)) #define pb push_bac ...
- qtwebkit 启动时间慢
qtwebkit 启动时间慢 qtwebkit 启动时间慢 qtwebkit 启动时间慢
- faiss的简单使用
简介 faiss是为稠密向量提供高效相似度搜索和聚类的框架.由Facebook AI Research研发. 具有以下特性. 1.提供多种检索方法 2.速度快 3.可存在内存和磁盘中 4.C++实现, ...
- ORACLE复杂查询之子查询
子查询分为两类:标准子查询和相关子查询. 一.标准子查询:子查询先于主查询独立执行,返回明确结果供主查询使用. 子查询只执行一次,不依赖于主查询. 例如: 其中子查询能够返回结果:2450.所以断定其 ...
- 【NOIP2014模拟8.17】Magical GCD
题目 对于一个由正整数组成的序列, Magical GCD 是指一个区间的长度乘以该区间内所有数字的最大公约数.给你一个序列,求出这个序列最大的 Magical GCD. 分析 根据暴力的思想, \( ...
- sh_03_程序计数
sh_03_程序计数 # 打印 5 遍 Hello Python # 1. 定义一个整数变量,记录循环次数 i = 0 # 2. 开始循环 while i < 3: # 1> 希望在循环内 ...
- 线程工具类ThreadUtils
package yqw.java.util; public class ThreadUtils { /** * showThreadInfo * * @return ...
- jQuery_完成表格的隔行换色
表格的颜色一样不利于区分,而利用jQuery则可以很方便的进行表格的隔行换色操作,原表如下: 这样看着很不方便,但是隔行换色之后非常便捷清楚. 代码如下: <!DOCTYPE html> ...
- oracle调整链接数
50用户以下:8GB 混用,oracle 占据1GB~3GB内存,open_cursors:300,processes:10050-100用户:16GB 混用,oracle 占据3~4GB内存,ope ...