在上一篇文章中,我主要是设置了代理IP,虽然得到了相关的信息,但是打印出来的信息量有点多,要知道每打印一页,15个小说的信息全部会显示而过,有时因为屏幕太小,无法显示全所有的小说信息,那么,在这篇文章中,我主要想通过设置回车来控制每一条小说信息的输出,当我按下回车时,会显示下一条小说的信息,按“Q”时,会退出程序,同时,这个方法还会根据包含小说信息的页面数量来决定是否加载新的一页。

首先,我们导入一些模块,定义一个类,初始化方法,定义一些变量:

self.Novels里存放的是小说信息的变量,每一个元素是每一页的小说信息们

self.load决定程序是否继续运行的变量

 #-*-coding:utf-8-*-
 import urllib2
 from bs4 import BeautifulSoup

 class dbxs:

     def __init__(self):
         self.pageIndex = 0
         self.Novels = []
         self.load = False

然后,我们获得html页面的内容,在这里,我们为了能够得到信息,而不让豆瓣服务器查封我们的IP,我们设置了请求的头部信息headers和代理IP。

     def getPage(self, pageIndex):
         #设置代理IP
         enable_proxy = True
         proxy_handler = urllib2.ProxyHandler({'Http': '116.30.251.210:8118'})
         null_proxy_handler = urllib2.ProxyHandler({})
         if enable_proxy:
             opener = urllib2.build_opener(proxy_handler)
         else:
             opener = urllib2.build_opener(null_proxy_handler)
         urllib2.install_opener(opener)

         #设置headers,模拟浏览器登录
         try:
             url = 'https://www.douban.com/tag/%E5%B0%8F%E8%AF%B4/book' +'?start=' + str(pageIndex)
             my_headers = {'User-Agent':'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:55.0)'}
             request =   urllib2.Request(url, headers = my_headers)
             response = urllib2.urlopen(request)
             return response.read()
19      except urllib2.URLError, e:
             if hasattr(e, "code"):
                 print e.code
             if hasattr(e, "reason"):
                 print e.reason
                 return None 

我们获得的是html源码,源码里有包含我们想要的元素,但是为了方便抓取数据,利用BeautifulSoup解析文档,这里我们用的解析器是html.parser。

这里的pageNovels是一个列表,存放的是每一页的所有小说信息,当某一小说信息没有rate一项时,这一条小说信息没有rates。

     def getPageItems(self, pageIndex):
         pageCode = self.getPage(pageIndex)
         soup = BeautifulSoup(pageCode, 'html.parser')
         contents = soup.find_all('dd')
         pageNovels = []
         if contents:
             for item in contents:
                 title = item.find(class_ = 'title').string
                 info = item.find(class_ = 'desc').string.strip()
                 rate = item.find(class_ = 'rating_nums')  #这里不能加string,如果rate不存在,那么程序会报错:NoneType没有.string属性
                 if rate:
                     rates = rate.string
                     pageNovels.append([title, info, rates])
                 else:
                     pageNovels.append([title, info])
             return pageNovels
         else:
             pageNovels.append('end')
             return pageNovels        

需要定义一个加载页,当self.Novels里的页数小于2,则程序加载下一页

     def loadPage(self):
         if self.load == True:
             if len(self.Novels) < 2:
                 pageNovels = self.getPageItems(self.pageIndex)
                 if pageNovels:
                     self.Novels.append(pageNovels)
                     self.pageIndex += 15    

为了获得每一页的每一条小说信息,我们需要定义一个getOneContent的方法

     def getOneContent(self, pageNovels, page):
         for item in pageNovels:
             input = raw_input()
             self.loadPage()
             if input == "Q":
                 self.load = False
                 print u"已退出查看"
                 return None
             #if item[2]:      #这里不能用if itme[2],当item[2]不存在时,会报错
             if len(item) == 3:
                 print u"第%d页 %s\n%s\n评分:%s\n" %(page, item[0], item[1], item[2])
             else:
                 print u"第%d页 %s\n%s\n" %(page, item[0], item[1]) 

最后,我们得定义一个开始方法

     def start(self):
         print u"正在读取豆瓣小说信息,按回车查看新内容,Q退出"
         self.load = True
         self.loadPage()
         nowPage = 0
         while self.load:
             if len(self.Novels) > 0:
                 pageNovels = self.Novels[0]
                 nowPage += 1
                 del self.Novels[0]
                 self.getOneContent(pageNovels, nowPage)
                 if self.Novels[0] == ['end']:
                     self.load = False
                     print u'所有页面已加载完'

整理一下,最后的总代码:

 #-*-coding:utf-8-*-
 import urllib2
 from bs4 import BeautifulSoup
 import time
 import random

 class dbxs:

     def __init__(self):
         self.pageIndex = 0
         self.Novels = []
         self.load = False

     #获取html页面的内容
     def getPage(self, pageIndex):
         #设置代理ip
         enable_proxy = True
         proxy_handler = urllib2.ProxyHandler({'Http': '116.30.251.210:8118'})
         null_proxy_handler = urllib2.ProxyHandler({})
         if enable_proxy:
             opener = urllib2.build_opener(proxy_handler)
         else:
             opener = urllib2.build_opener(null_proxy_handler)
         urllib2.install_opener(opener)
         try:
             url = 'https://www.douban.com/tag/%E5%B0%8F%E8%AF%B4/book' + "?start=" + str(pageIndex)
             #设置请求头部信息,模拟浏览器的行为
             my_headers = {'User-Agent':'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:55.0)'}
             request =   urllib2.Request(url, headers = my_headers)
             response = urllib2.urlopen(request)
             return response.read()
         except urllib2.URLError, e:
             if hasattr(e, "code"):
                 print e.code
             if hasattr(e, "reason"):
                 print e.reason
                 return None

     def getPageItems(self, pageIndex):
         pageCode = self.getPage(pageIndex)
         soup = BeautifulSoup(pageCode, 'html.parser')
         contents = soup.find_all('dd')
         pageNovels = []
         if contents:
             for item in contents:
                 title = item.find(class_ = 'title').string
                 info = item.find(class_ = 'desc').string.strip()
                 rate = item.find(class_ = 'rating_nums')  #这里不能加string,如果rate不存在,那么程序会报错:NoneType没有.string属性
                 if rate:
                     rates = rate.string
                     pageNovels.append([title, info, rates])
                 else:
                     pageNovels.append([title, info])
             return pageNovels
         else:
             pageNovels.append('end')
             return pageNovels

     def loadPage(self):
         if self.load == True:
             if len(self.Novels) < 2:
                 pageNovels = self.getPageItems(self.pageIndex)
                 if pageNovels:
                     self.Novels.append(pageNovels)
                     self.pageIndex += 15

     #打印每一个小说的信息
     def getOneContent(self, pageNovels, page):
         for item in pageNovels:
             input = raw_input()
             self.loadPage()
             if input == "Q":
                 self.load = False
                 print u"已退出查看"
                 return None
             #if item[2]:      #这里不能用if itme[2],当item[2]不存在时,会报错
             if len(item) == 3:
                 print u"第%d页 %s\n%s\n评分:%s\n" %(page, item[0], item[1], item[2])
             else:
                 print u"第%d页 %s\n%s\n" %(page, item[0], item[1])            

     #创建一个开始方法
     def start(self):
         print u"正在读取豆瓣小说信息,按回车查看新内容,Q退出"
         self.load = True
         self.loadPage()
         nowPage = 0
         while self.load:
             if len(self.Novels) > 0:
                 pageNovels = self.Novels[0]
                 nowPage += 1
                 del self.Novels[0]
                 self.getOneContent(pageNovels, nowPage)
                 if self.Novels[0] == ['end']:
                     self.load = False
                     print u'所有页面已加载完'

 DBXS = dbxs()
 DBXS.start()

有必要解释一下self.Novels和PageNovels

Python爬虫之利用BeautifulSoup爬取豆瓣小说(二)——回车分段打印小说信息的更多相关文章

  1. Python爬虫之利用BeautifulSoup爬取豆瓣小说(一)——设置代理IP

    自己写了一个爬虫爬取豆瓣小说,后来为了应对请求不到数据,增加了请求的头部信息headers,为了应对豆瓣服务器的反爬虫机制:防止请求频率过快而造成“403 forbidden”,乃至封禁本机ip的情况 ...

  2. python爬虫:利用BeautifulSoup爬取链家深圳二手房首页的详细信息

    1.问题描述: 爬取链家深圳二手房的详细信息,并将爬取的数据存储到Excel表 2.思路分析: 发送请求--获取数据--解析数据--存储数据 1.目标网址:https://sz.lianjia.com ...

  3. Python爬虫之利用BeautifulSoup爬取豆瓣小说(三)——将小说信息写入文件

    #-*-coding:utf-8-*- import urllib2 from bs4 import BeautifulSoup class dbxs: def __init__(self): sel ...

  4. python爬虫:利用正则表达式爬取豆瓣读书首页的book

    1.问题描述: 爬取豆瓣读书首页的图书的名称.链接.作者.出版日期,并将爬取的数据存储到Excel表格Douban_I.xlsx中 2.思路分析: 发送请求--获取数据--解析数据--存储数据 1.目 ...

  5. Python爬虫使用lxml模块爬取豆瓣读书排行榜并分析

    上次使用了BeautifulSoup库爬取电影排行榜,爬取相对来说有点麻烦,爬取的速度也较慢.本次使用的lxml库,我个人是最喜欢的,爬取的语法很简单,爬取速度也快. 本次爬取的豆瓣书籍排行榜的首页地 ...

  6. Python爬虫之利用正则表达式爬取内涵吧

    首先,我们来看一下,爬虫前基本的知识点概括 一. match()方法: 这个方法会从字符串的开头去匹配(也可以指定开始的位置),如果在开始没有找到,立即返回None,匹配到一个结果,就不再匹配. 我们 ...

  7. Python爬虫实战一之爬取糗事百科段子

    大家好,前面入门已经说了那么多基础知识了,下面我们做几个实战项目来挑战一下吧.那么这次为大家带来,Python爬取糗事百科的小段子的例子. 首先,糗事百科大家都听说过吧?糗友们发的搞笑的段子一抓一大把 ...

  8. python爬虫学习01--电子书爬取

    python爬虫学习01--电子书爬取 1.获取网页信息 import requests #导入requests库 ''' 获取网页信息 ''' if __name__ == '__main__': ...

  9. Python爬虫:为什么你爬取不到网页数据

    前言: 之前小编写了一篇关于爬虫为什么爬取不到数据文章(文章链接为:Python爬虫经常爬不到数据,或许你可以看一下小编的这篇文章), 但是当时小编也是胡乱编写的,其实里面有很多问题的,现在小编重新发 ...

随机推荐

  1. 使用QFuture类监控异步计算的结果

    版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/Amnes1a/article/details/65630701在Qt中,为我们提供了好几种使用线程的 ...

  2. Vue中浏览器的的前进和后退

    项目开发的时候,有时候可能需要我们来对页面后退和前进,这个东西跟浏览器自带的前进后退功能很像,下面来大致讲一下在vue中浏览器的前进和后退 一.后退功能 vue中的后退有好多种方法可以使用,使用这些方 ...

  3. MC20模块教程目录

    MC20模块使用教程 为了阅读和修正方便,所有教程在线观看,请在有网络的环境下观看下面教程,谢谢! MC20模块教程在线目录 第一章:基础使用,使用电脑调试MC20的各项功能 1.1 使用电脑测试MC ...

  4. mysql数据库补充知识3 查询数据库记录信息之多表查询

    一 介绍 准备表 company.employeecompany.department 复制代码 #建表 create table department( id int, name varchar(2 ...

  5. assign,copy,retain的区别以及weak和strong的区别

    @property (nonatomic, assign) NSString *title;    什么是assign,copy,retain之间的区别?      assign: 简单赋值,不更改索 ...

  6. LeetCode:杨辉三角【118】

    LeetCode:杨辉三角[118] 题目描述 给定一个非负整数 numRows,生成杨辉三角的前 numRows 行. 在杨辉三角中,每个数是它左上方和右上方的数的和. 示例: 输入: 5 输出: ...

  7. Fidder详解之抓包

    前言 本文是博主发表的第一篇文章,如有傻逼之处,请大家见谅.最近遇到很多人说接口相关的问题,比如:什么是接口,我该怎么做接口测试,还有我总是抓不到APP上的https请求(这个巨坑,不知道坑了多少小白 ...

  8. 使用Axure生成网站结构图

    使用Axure设计的各网站(产品)页面,生成网站(产品)结构图.这个对于了解网站整体结构很有帮助. 需要把它生成对应结构的网站结构图. 第一步:在“主页”上面新建一个和“主页”平级的页面,命名为“网站 ...

  9. matlab 读取nc

    在这里做个记录,这几个是matlab用来读取.nc格式数据的函数.只是函数,参数和变量为了便于理解,取括号中的名字.   fid=netcdf.open('fname','nowriter');%打开 ...

  10. flex for循环

    //for ..in 循环中的迭代变量包含属性所保存的值和名称 //for each..in 循环中的迭代变量只包含属性所保存的值,而不包含属性的名称 //对象遍历,可以获取属性名称 private ...