python——爬虫&问题解决&思考(三)
继续上一篇文章的内容,上一篇文章中,将爬虫调度器已经写好了,调度器是整个爬虫程序的“大脑”,也可以称之为指挥中心。而现在,我们要做的就是去将调度器中用到的其他组件写好。首先是url管理器,它既然作为管理器,那么它一定要区分待爬取的url和已经爬取的url,否则会重复爬取。这里教程用的是set集合,将两个url暂时存放到集合中,也就是内存中,毕竟比较爬取的数据比较少,当然也可以存放到别的地方,比如缓存或者关系型数据库中。

从图中可以看出,一共出现5次:
第一次是调度器初始化函数中,创建这个urlmanager对象,
第二次是调用了add_new_url方法来将最初始的url加入到带爬取的集合中,
第三次是在爬取过程中来判断是否有待爬取的url,
第四次是将要爬取的url从集合中取出来,
第五次是将页面解析出来的新的一组url再次添加到带爬去集合中
那么我们接下来就要做的是用代码来实现这些功能:
 class UrlManager(object):
     """docstring for UrlManager"""
     def __init__(self):
         self.new_urls = set()
         self.old_urls = set()
     #向管理器中添加一个新的url
     def add_new_url(self,url):
         if url is None:
             return
         if url not in self.new_urls and url not in self.old_urls:
             self.new_urls.add(url)
     #从爬取数据中向管理器中批量添加url
     def add_new_urls(self,urls):
         if urls is None or len(urls) == 0:
             return
         for url in urls:
             self.add_new_url(url)
     #判断是否有新的url
     def has_new_url(self):
         return (len(self.new_urls) != 0)
     #从管理器中取出一个新的url
     def get_new_url(self):
         new_url = self.new_urls.pop()
         self.old_urls.add(new_url)
         return new_url
好,到这,url管理器就搞定了!
接下来就是url下载器了,很简单一个功能,将程序访问的页面保存下来。
  
从上图可以看出,下载器只在调度器中出现过两次:
第一次是初始化的时候创建
第二次是紧接着取到url之后,马上调用它来下载页面
在url下载器中,原教程使用的是urllib库,我觉得有点繁琐。所以我换成了一个更好用的库:requests。这个库可以帮助我屏蔽许多技术难题,直接去抓取我们想要访问的页面,而且使用起来非常简单。
 import requests
 class HtmlDownloader(object):
     """docstring for HtmlDownloader"""
     def download(self,url):
         if url is None:
             return
         response = requests.get(url, timeout = 0.1)
         response.encoding = 'utf-8'
         if response.status_code == requests.codes.ok:
             return response.text
         else:
             return 
简要讲一下这段代码:
a.首先要导入requests库,这个因为是第三方库,所以需要你自己下载 ,在命令行 输入 :pip install requests
b.然后开始写下载器这个类,这个类只有一个方法,就是download。这个方法首先会接受你给定的url,然后对其进行判断是否存在。
c.然后调用requests的get方法,它里面接受两个参数,一个是url,还有一个是timeout
timeout是我自己额外加进去的,就是访问超时。如果不加timeout,程序会假死,也就是说会一直在那里等待页面的响应,也不抛出异常。
d.然后对返回的response进行编码设置,因为爬取的百度百科页面是utf-8,所以这里最好还是设置一下,虽然requests会智能判断,但是还是手动改一下为宜。
e.然后在判断页面是否响应,这里的codes.ok其实就是200,表示网页正常响应,你这里直接写 response.status_code == 200 也没问题。
f.最后,将页面的所有内容都返回,这里的text就是一个字符串,它包含了一个页面的所有代码(html,css,js)。
python——爬虫&问题解决&思考(三)的更多相关文章
- python——爬虫&问题解决&思考(1)
		
最近刚接触python,找点小任务来练练手,希望自己在实践中不断的锻炼自己解决问题的能力.这个小爬虫来自慕课网的一门课程,我在这里记录的是自己学习的过程中遇到的问题和解决方法以及爬虫之外的思考. 这次 ...
 - python——爬虫&问题解决&思考(四)
		
继续上一篇文章的内容,上一篇文章中已经将url管理器和下载器写好了.接下来就是url解析器,总的来说这个模块是几个模块中比较难的.因为通过下载器下载完页面之后,我们虽然得到了页面,但是这并不是我们想要 ...
 - Python爬虫学习:三、爬虫的基本操作流程
		
本文是博主原创随笔,转载时请注明出处Maple2cat|Python爬虫学习:三.爬虫的基本操作与流程 一般我们使用Python爬虫都是希望实现一套完整的功能,如下: 1.爬虫目标数据.信息: 2.将 ...
 - 路飞学城-Python爬虫集训-第三章
		
这个爬虫集训课第三章的作业讲得是Scrapy 课程主要是使用Scrapy + Redis实现分布式爬虫 惯例贴一下作业: Python爬虫可以使用Requests库来进行简单爬虫的编写,但是Reque ...
 - Python爬虫学习笔记(三)
		
Cookies: 以抓取https://www.yaozh.com/为例 Test1(不使用cookies): 代码: import urllib.request # 1.添加URL url = &q ...
 - Python 爬虫入门(三)—— 寻找合适的爬取策略
		
写爬虫之前,首先要明确爬取的数据.然后,思考从哪些地方可以获取这些数据.下面以一个实际案例来说明,怎么寻找一个好的爬虫策略.(代码仅供学习交流,切勿用作商业或其他有害行为) 1).方式一:直接爬取网站 ...
 - python爬虫入门(三)XPATH和BeautifulSoup4
		
XML和XPATH 用正则处理HTML文档很麻烦,我们可以先将 HTML文件 转换成 XML文档,然后用 XPath 查找 HTML 节点或元素. XML 指可扩展标记语言(EXtensible Ma ...
 - Python爬虫实例(三)代理的使用
		
一些网站会有相应的反爬虫措施,例如很多网站会检测某一段时间某个IP的访问次数,如果访问频率太快以至于看起来不像正常访客,它可能就会会禁止这个IP的访问.所以我们需要设置一些代理服务器,每隔一段时间换一 ...
 - Python爬虫基础(三)urllib2库的高级使用
		
Handler处理器 和 自定义Opener opener是 urllib2.OpenerDirector 的实例,其中urlopen是模块默认构建的opener. 但是基本的urlopen()方法不 ...
 
随机推荐
- 【Scala】Scala之Traits
			
一.前言 前面学习了Scala中包和导入的相关知识点,接着学习Traits(特质) 二.Traits Scala的特质与Java的接口基本相同,当遇到可以使用Java接口的情形,就可以考虑使用特质,S ...
 - Jmeter如何将上一个请求的结果作为下一个请求的参数——使用正则表达式提取器
			
首先在线程组下添加两个HTTP请求, 添加好两个HTTP请求后,在每个HTTP请求下添加一个查看结果数 在第一个HTTP请求下添加正则表达式提取器 在第一个HTTP请求添加好IP地址,路径,端口号,协 ...
 - Lucene工作原理
			
Lucene是一个高性能的java全文检索工具包,它使用的是倒排文件索引结构.该结构及相应的生成算法如下: 0)设有两篇文章1和2 文章1的内容为:Tom lives in Guangzhou,I l ...
 - 【微信小程序】认识微信小程序
			
目前微信小程序已经支持个人版了 罗列一下微信开发的一些资料和工具 (如果你还不了解微信小程序如何操作请点击 新手教程 )里面罗列了 开发者工具 如何使用 和 微信的基本操作 很详细 一.微信开发者工 ...
 - 关于Integer与int
			
integer a=new integer(1); integer b=new integer(1); int c=1; integer d=1; a==b false因为地址不同: a==c t ...
 - VueJS 组件参数名命名方式和前台显示
			
camelCase(驼峰式) 和. kebab-case(短横线式) HTML 特性是不区分大小写的.所以,当使用的不是字符串模版,camelCased (驼峰式) 命名的 prop 需要转换为相对应 ...
 - Intellij IDEA快捷键(必备)
			
快捷键 功能描述 Ctrl + Shift + Space 智能代码提示(必备) Ctrl + R 在当前文件进行文本替换 Ctrl + F 在当前文件进行文本查找 Ctrl + Y 删除光标所在行 ...
 - 利用LinkedList生成一副扑克牌
			
import java.util.LinkedList; import java.util.Random; //自定义一个Poker类,用于存储扑克的信息(花色.数字) class Poker{ St ...
 - ionic创建项目遇到的各种问题
			
前提:执行创建语句的前提是ionic环境已经装好,开始执行ionic start myApp blank. 提示已经有同名项目,是否覆盖.这里创建的是一个blank(空) 的ionic项目.还要两种是 ...
 - 利用Python进行简单的图像识别(验证码)
			
这是一个最简单的图像识别,将图片加载后直接利用Python的一个识别引擎进行识别 将图片中的数字通过 pytesseract.image_to_string(image)识别后将结果存入到本地的txt ...