笔记,爬虫(1)
枯燥的学停一下,这些天尝试攻克爬虫(Python3以上版本)的最基础难关:
参考(博主写得很用心,支持原版,五星推荐):http://blog.csdn.net/database_zbye/article/details/38826893
一.网络爬虫的定义
网络爬虫是一个自动提取网页的程序,它为搜索引擎从Web上下载网页,是搜索引擎的重要组成部分。通用网络爬虫从一个或若干初始网页的URL开始,获得初始网页上的URL列表;在抓取网页的过程中,不断从当前页面上抽取新的URL放入待爬行队列,直到满足系统的停止条件。
二.爬虫的原理
爬虫的原理相对简单,其爬取网页的基本步骤大致如下:
1) 人工给定一个URL 作为入口,从这里开始爬取。
万维网的可视图呈蝴蝶型,网络爬虫一般从蝴蝶型左边结构出发。这里有一些门户网站的主页,而门户网站中包含大量有价值的链接。
2) 用运行队列和完成队列来保存不同状态的链接。
对于大型数据量而言,内存中的队列是不够的,通常采用数据库模拟队列。用这种方法既可以进行海量的数据抓取,还可以拥有断点续抓功能。
3) 线程从运行队列读取队首URL ,如果存在,则继续执行,反之则停止爬取。
4) 每处理完一个URL ,将其放入完成队列,防止重复访问。
5) 每次抓取网页之后分析其中的URL,将经过过滤的合法链接写入运行队列,等待提取。
6) 重复步骤 3 )、4 )、5 )。
#最简单的输出网页所有信息
#encoding:UTF-8 import urllib.request url = "http://www.baidu.com" data = urllib.request.urlopen(url).read() data = data.decode('UTF-8') print(data)
结果,一堆字符:

自己看着办吧(详见Python documentation):
参考:http://www.yiibai.com/python/python3-webbug-series1.html
#如果要抓取百度上面搜索关键词为Jecvay Notes的网页, import urllib import urllib.request ''' data是一个字典, 然后通过urllib.parse.urlencode()来将data转换为 ‘word=Jecvay+Notes’的字符串, 最后和url合并为full_url, 其余和上面那个最简单的例子相同.关于urlencode(), 大概知道他是把一个通俗的字符串, 转化为url格式的字符串。 ''' data={} data['word']='Jecvay Notes' url_values=urllib.parse.urlencode(data) url="http://www.baidu.com/s?" full_url=url+url_values data=urllib.request.urlopen(full_url).read() data=data.decode('UTF-8') print(data)
结果:

import urllib import urllib.request ''' data是一个字典, 然后通过urllib.parse.urlencode()来将data转换为 ‘word=Jecvay+Notes’的字符串, 最后和url合并为full_url, 其余和上面那个最简单的例子相同.关于urlencode(), 大概知道他是把一个通俗的字符串, 转化为url格式的字符串。 ''' data={}#字典的构造,大括号 data['word']='Jecvay Notes' print(data)#这就是输出的效果:{'word': 'Jecvay Notes'} url_values=urllib.parse.urlencode(data) url="http://www.baidu.com/s?" #添加了/s? full_url=url+url_values print(full_url)#输出的效果:http://www.baidu.com/s?word=Jecvay+Notes
#筛选需要信息输出
''' ① 在Python中发送HTTP请求是非常简单的; urllib.request模块有一个方便的函数urlopen() ,输入"网址", 然后返回一个类文件对象,这时只要调用它的read()方法就可以获得网页的全部内容。 ② urlopen().read()方法总是返回bytes对象,而不是字符串。记住字节仅仅是字节,字符只是一种抽象,但HTTP服务器不关心抽象的东西。 所以请求一个资源,得到字节。需要用decode()解码,才能显式的将其转化成字符串。 ''' import urllib.request import re # Regular expression operations ######################################################## # # fetch函数功能:抓取“陕西建筑招标网”的第一页“招标公告”页面,输出公告名字 # # 参数baseUrl是要访问的网站地址 # ######################################################## def fetch(baseUrl): # 第1步:模拟浏览器发送请求 data = urllib.request.urlopen(baseUrl).read() # 二进制字节形式 data = data.decode('utf-8') # 第2步:页面返回后,利用正则表达式提取想要的内容 ''' .是任意字符 .?的意思是尽可能少的匹配 .*表示"贪婪匹配",首先匹配到不能匹配为止,根据后面的正则表达式,会进行回溯。 .*?表示"最小匹配",一旦匹配成功,不再往下进行。(具体见下英文) ''' nameList = [] nameList = re.compile(r'target="_blank" title="(.*?)"', re.DOTALL).findall(data) # 第3步:返回在页面上析取的“标题名” return nameList ####### 执行 ######## if __name__ == "__main__": # 要抓取的网页地址 url = "http://www.sxszbb.com/sxztb/jyxx/001001/MoreInfo.aspx?CategoryNum=001001" # 存放到名字列表中 NameList = fetch(url) # 输出 NameList Length = len(NameList) for i in range(0, Length): print("标题名%d:%s\n" % (i + 1, NameList[i]))
结果:


三.运行爬虫程序时常见的问题和解决方法?
爬虫程序在对某一站点抓取信息时,会在短时间内发送大量的request,这时会出现很多问题。这里我总结了常见的几个问题谈谈,
(1)因访问频繁,主机IP被暂时屏蔽
例如,因为访问频率高被禁止访问,收到很多"403 Forbidden"的提示信息。 解决方法:伪装成user agent(如上面例子);使用代理;IP池等。
(2)爬取速度
单线程爬虫抓取速度慢,可能会由于网络延时是线程陷入阻塞。 解决方法:采用多线程实现。
(3)容错处理
如抓取页面不规整导入正则表达式找不出信息,延时,传输出错等各种错误。 解决方法:异常处理,提高健壮性;

浙公网安备 33010602011771号