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

爬取豆瓣小说的链接:https://www.douban.com/tag/%E5%B0%8F%E8%AF%B4/book?start=0

获取免费代理ip的网站:http://www.xicidaili.com/

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

 class dbxs:

     def __init__(self):
         self.pageIndex = 0
         self.enable = True

     #获取html页面的内容
     def getPage(self, pageIndex):
         try:
             #设置代理ip
             enable_proxy = True
             #Openers使用处理器Handlers,所有的“繁重”工作由Handlers处理,每个handlers知道如何通过特定协议打开URLs,或者如何处理URL打开时的各个方面
             #在你使用代理上网或其他的情况就需要自己创建一个opener,可以实例化一个OpenerDirector,然后调用.add_handler(some_handler_instance)
             #也可使用build_opener,这是一个更加方便的函数,用来创建opener对象,它只需要一次函数调用
             proxy_handler = urllib2.ProxyHandler({'Http': '113.118.170.230:808'})
             null_proxy_handler = urllib2.ProxyHandler({})
             if enable_proxy:
             #当你获取一个URL你要使用一个opener,默认情况下opener是urlopen,但urllib2.urlopen()不支持验证、cookie或者其他Http高级功能
             #要支持这些功能,必须使用build_opener()创建自定义opener对象,build_opener([handler1 [handler2,...]]),参数handler是Handlers的实例,常用的有HTTPBasicAuthHandler、HTTPCookieProcessor、ProxyHandler
                 opener = urllib2.build_opener(proxy_handler)
             else:
                 opener = urllib2.build_opener(null_proxy_handler)
             urllib2.install_opener(opener)   #install_opener用来创建(全局)默认opener,这个表示调用urlopen将使用你安装的opener
             #获得页面响应的内容
             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()

             #另外一种随机设置请求头部信息的方法
             #my_headers =['Mozilla/5.0 (Windows NT 6.1; WOW64; rv:55.0)', 'Mozilla/5.0 (Windows NT 6.1; Win64; x64)', 'Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0)']
             #header = random.choice(my_headers)    #random.choice()可以从任何序列,比如list列表中,选取一个随机的元素返回,可以用于字符串、列表、元组
             #request = urllib2.Request(url, headers = {'User-Agent': header})
         except urllib2.URLError, e:
             if hasattr(e, "code"):
                 print e.code
             if hasattr(e, "reason"):
                 print e.reason
                 return None

     #过滤查找这一页的小说名字,信息和评分
     def getContent(self, pageIndex):
         pageCode = self.getPage(pageIndex)
         soup = BeautifulSoup(pageCode, 'html.parser')
         #在获得相应的内容中找出所有标签为<dd>的内容(里面包含了我们需要的小说信息)
         contents = soup.find_all('dd')
         #如果contents为真,能够获取到包含<dd>标签的内容,什么情况获取不到?我们发现豆瓣小说21页之后的所有页面里都不包含<dd>标签,我们应该停止打印
         if contents:
         #item为包含小说信息的每一页的内容
             for item in contents:
                 title = item.find(class_ = 'title').string
                 info = item.find(class_ = 'desc').string.strip()
                 rate = item.find(class_ = 'rating_nums')
                 #通过试验,我们发现某一页可能存在小说没有评分,如果我们不判断rate,那么可能就出现报错
                 if rate:
                     rates = rate.string
                     print u"%s\n%s\n评分:%s\n" %(title, info, rates)
                 #对于小说没有评分的内容,我们只打印小说名字,信息
                 else:
                     print u"%s\n%s\n" %(title, info)
         #如果页面不包含<dd>标签,我们应该停止
         else:
             print u"所有页面已加载完"
             self.enable = False

         return contents

     #创建一个开始方法
     def start(self):
         #打印第一页,此时self.pageIndex = 0,初始化时设置了
         #设置页码x = 1
         x = 1
         #我们观察发现,第二页的pageIndex - 第一页的 = 第一页的小说的个数
         #我们执行self.getContent的同时,获取了第一页的小说的个数
         page_num = len(self.getContent(self.pageIndex))
         print u"第%s页" %x

         #利用self.enable控制下一页的打印
         while self.enable == True:
             #设置下一页的pageIndex
             self.pageIndex += page_num
             #页码+1
             x += 1
             #time.sleep(1)    #可以利用time模块来设置sleep时间
             #再次调用self.getContent的同时,获取当前页的小说的个数
             page_num = len(self.getContent(self.pageIndex))
             #在self.getContent中,如果不能获取到<dd>的内容,self.enable将会改为False,如果我们不加self.enable判断,仍会打印不存在小说信息的页码           if self.enable == True: 99               print u"第%s页" %x

 DBXS = dbxs()
 DBXS.start()

Python爬虫之利用BeautifulSoup爬取豆瓣小说(一)——设置代理IP的更多相关文章

  1. Python爬虫之利用BeautifulSoup爬取豆瓣小说(二)——回车分段打印小说信息

    在上一篇文章中,我主要是设置了代理IP,虽然得到了相关的信息,但是打印出来的信息量有点多,要知道每打印一页,15个小说的信息全部会显示而过,有时因为屏幕太小,无法显示全所有的小说信息,那么,在这篇文章 ...

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

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

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

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

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

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

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

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

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

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

  7. Python爬虫实战二之爬取百度贴吧帖子

    大家好,上次我们实验了爬取了糗事百科的段子,那么这次我们来尝试一下爬取百度贴吧的帖子.与上一篇不同的是,这次我们需要用到文件的相关操作. 前言 亲爱的们,教程比较旧了,百度贴吧页面可能改版,可能代码不 ...

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

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

  9. 转 Python爬虫实战二之爬取百度贴吧帖子

    静觅 » Python爬虫实战二之爬取百度贴吧帖子 大家好,上次我们实验了爬取了糗事百科的段子,那么这次我们来尝试一下爬取百度贴吧的帖子.与上一篇不同的是,这次我们需要用到文件的相关操作. 本篇目标 ...

随机推荐

  1. Vue中使用定时器setInterval和setTimeout

    js中定时器有两种,一个是循环执行setInterval,另一个是定时执行setTimeout 一.循环执行(setInterval) 顾名思义,循环执行就是设置一个时间间隔,每过一段时间都会执行一次 ...

  2. mprotect() failed: Cannot allocate memory

    遇到这个问题是在測试项目的性能时发现的,每一个对象分配一页大小的空间然后mprotect() 保护起来,当系统分配3W多个页的时候会出现这个问题. google到在一份邮件列表中也曾提到该问题.htt ...

  3. Android Studio的快捷键

    Android Studio可以在setting的keymaps设置快捷键,但最好使用该默认的快捷键. 生成TAG: logt 控制台打印带参的log:logm 代码提示:ctrl + alt + s ...

  4. Python的模块与函数以及与自动化的结合

    3 模块与函数 3.1程序结构 python的程序由package,module,function组成,分别是包,模块,函数.模块是函数和类的集合,包,模块,函数之间的关系如下: 3.2模块 pyth ...

  5. sequence.c

    /* * sequence.c */ #include <stdio.h> #include <memory.h> /* * SM3算法产生的哈希值大小(单位:字节) */ # ...

  6. Linux Shell基础 环境变量

    环境变量 环境变量和用户自定义变量最主要的区别在于,环境变量是全局变量,而用户自定义变量是局部变量.用户自定义变量只在当前的 Shell 中生效,而环境变量会在当前 Shell 和这个 Shell 的 ...

  7. Vue全家桶 vue + vue-router + vuex

    Vue实例的生命周期钩子函数(8个)        1. beforeCreate             data属性光声明没有赋值的时候        2. created             ...

  8. Python编程-绑定方法、软件开发

    一.绑定方法与非绑定方法 1.绑定方法 绑定给谁,谁来调用就自动将它本身当作第一个参数传入 (1)绑定到类的方法:用classmethod装饰器装饰的方法. 为类量身定制 类.boud_method( ...

  9. libstdc和glibc的一些共享库问题

    1./usr/lib/libstdc++.so.6: version `GLIBCXX_3.4.15' not found错误的解决 原因是没有GLIBCXX_3.4.15版本,或是更高的版本输入命令 ...

  10. 摊铺机基本参数介绍(三一重工SSP220C-5)

    三一重工SSP220C-5稳定土摊铺机参数 SSP系列稳定土摊铺机SSP220C-5 动力强劲162kw 动力充分满足摊铺机各种工况下动力需求 高效任何工况,确保摊铺能力大于900t/h,行业内绝无仅 ...