python制作小说爬虫实录


Posted in Python onAugust 14, 2017

纪念我的第一个爬虫程序,一共写了三个白天,其中有两个上午没有看,中途遇到了各种奇怪的问题,伴随着他们的解决,对于一些基本的操作也弄清楚了。果然,对于这些东西的最号的学习方式,就是在使用中学习,通过解决问题的方式来搞定这些知识。按需索取,才能更有针对性。

大体记录下整个过程。

--------------------------------------------------------------------------------

准备构思

出于对于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(),返回一个所有结果组成的列表。可以及时返回输出其内容,进而选择合适的部分进行处理。

python 正则表达式

通过查看相关的符号,这里使用(.+?)来实现匹配非贪婪模式(尽量少的)下任意无限字符,对之使用(),进而匹配括号内的模式。

文件写入

使用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学习笔记:字典的使用示例详解
Jun 13 Python
Python 正则表达式(转义问题)
Dec 15 Python
MySQL中表的复制以及大型数据表的备份教程
Nov 25 Python
Python实现批量更换指定目录下文件扩展名的方法
Sep 19 Python
python对矩阵进行转置的2种处理方法
Jul 17 Python
python多进程重复加载的解决方式
Dec 13 Python
Python+opencv+pyaudio实现带声音屏幕录制
Dec 23 Python
Python函数基本使用原理详解
Mar 19 Python
使用Python将Exception异常错误堆栈信息写入日志文件
Apr 08 Python
Keras load_model 导入错误的解决方式
Jun 09 Python
python 批量压缩图片的脚本
Jun 02 Python
Python 中 Shutil 模块详情
Nov 11 Python
python安装Scrapy图文教程
Aug 14 #Python
基于python时间处理方法(详解)
Aug 14 #Python
关于Django外键赋值问题详解
Aug 13 #Python
python爬虫实战之最简单的网页爬虫教程
Aug 13 #Python
详解python中executemany和序列的使用方法
Aug 12 #Python
mysql 之通过配置文件链接数据库
Aug 12 #Python
python+selenium开发环境搭建图文教程
Aug 11 #Python
You might like
php分页函数
2006/07/08 PHP
C# WinForm中实现快捷键自定义设置实例
2015/01/23 PHP
无需数据库在线投票调查php代码
2016/07/20 PHP
php 计算两个时间相差的天数、小时数、分钟数、秒数详解及实例代码
2016/11/09 PHP
PHP的PDO大对象(LOBs)
2019/01/27 PHP
用javascript实现改变TEXTAREA滚动条和按钮的颜色,以及怎样让滚动条变得扁平
2007/04/20 Javascript
一个js实现的所谓的滑动门
2007/05/23 Javascript
window.open被浏览器拦截后的自定义提示效果代码
2007/11/19 Javascript
精通Javascript系列之数值计算
2011/06/07 Javascript
在表单提交前进行验证的几种方式整理
2013/07/31 Javascript
js实现无需数据库的县级以上联动行政区域下拉控件
2013/08/14 Javascript
使用JQUERY进行后台页面布局控制DIV实现左右式
2014/01/07 Javascript
jquerymobile局部渲染的各种刷新方法小结
2014/03/05 Javascript
javascript实现相同事件名称,不同命名空间的调用方法
2015/06/26 Javascript
Javascript闭包实例详解
2015/11/29 Javascript
详解JavaScript的AngularJS框架中的作用域与数据绑定
2016/03/04 Javascript
javascript检查某个元素在数组中的索引值
2016/03/30 Javascript
JQuery学习总结【一】
2016/12/01 Javascript
微信公众平台开发教程(四) 实例入门:机器人回复(附源码)
2016/12/02 Javascript
vue实现点击关注后及时更新列表功能
2018/06/26 Javascript
详解element-ui级联菜单(城市三级联动菜单)和回显问题
2019/10/02 Javascript
简单了解Vue computed属性及watch区别
2020/07/10 Javascript
[01:03:27]NAVI vs EG 2019国际邀请赛小组赛 BO2 第一场 8.15
2019/08/17 DOTA
Python抓取电影天堂电影信息的代码
2016/04/07 Python
基于Django的ModelForm组件(详解)
2017/12/07 Python
Python通过for循环理解迭代器和生成器实例详解
2019/02/16 Python
python中selenium操作下拉滚动条的几种方法汇总
2019/07/14 Python
Python实现快速排序的方法详解
2019/10/25 Python
Python实现栈的方法详解【基于数组和单链表两种方法】
2020/02/22 Python
关于matplotlib-legend 位置属性 loc 使用说明
2020/05/16 Python
python中列表的含义及用法
2020/05/26 Python
CSS3文本换行word-wrap解决英文文本超过固定宽度不换行
2013/10/10 HTML / CSS
意大利在线药房:shop-farmacia.it
2019/03/12 全球购物
澳大利亚领先的女性运动服品牌:Lorna Jane
2020/06/19 全球购物
万豪国际住宅与别墅集团:Homes & Villas by Marriott International
2020/10/08 全球购物
大学生村官工作总结2015
2015/04/09 职场文书