爬虫:一段自动抓取互联网信息的程序
爬虫可以从一个URL出发,访问所有与之有关联的URL,从上面提取数据
简单得爬虫架构
爬虫调度端:开启,终止,监控爬虫运行程序
爬虫程序中有三个模块:
URL管理器:对爬取过的和将要爬取的URL数据的管理
网页下载器:从URL管理器中拿出一个待爬取的URL传送给网页下载器,下载器会将指定得URL下载下来,存储成一个字符串
网页解析器:字符串会传送给网页解析器进行解析,网页解析器一方面获取有价值的数据,另一方面获得网页中得URL补充到URL管理器
URL管理器,网页下载器和网页解析器形成了一个循环,只要有相关联得URL,则会一直循环下去。
URL管理器
URL管理器:管理待抓取URL集合和已抓取URL集合
防止重复抓取,防止循环抓取
URL管理器需要支持的功能:
1,添加新URL到待爬取集合中
2,判断待添加URL是否在容器中
3, 获取待爬取URL
4,判断是否还有待爬取URL
5,如果URL已爬取,则将URL从待爬取移动到已爬取
URL管理器实现方式
第一种:将已爬取和待爬取URL存储到内存中,例如python内存:将待爬取和已爬取的URL分别放到两个set()当中,因为set()具有自动去重功能。
第二种:将已爬取和待爬取URL存储到关系数据库中,例如MySQL:设置两个字段分别记录url和是否爬取过。urls(url,is_crawled)
第三种:将已爬取和待爬取URL存储到缓存数据库中,例如redis:redis本身支持set集合,我们将待爬取和已爬取的URL分别放到两个set()当中。
网页下载器
网页下载器:将互联网上URL对应得网页下载到本地的工具
网页下载器将URL对应的网页以HTML的格式下载到本地,存储成一个本地文件或者内存字符串
python有哪几种网页下载器?
urllib2:python官方基础模块
requests:第三方包
网页下载器--urllib2
下载网页方法1:最简洁方法
使用urlopen()方法
import urllib.request #直接请求 response=urllib.request.urlopen("https://www.baidu.com") #获取状态码,如果是200表示获取成功 print(response.code) #读取内容 cont=response.read().decode('UTF-8') print(cont)
下载网页方法2:添加data,http header
将url,data,header添加到请求当中
网页解析器
网页解析器:从网页中获取有价值数据的工具
网页解析器从下载下来的html网页字符串获取到价值数据和新的URL列表
python有哪几种网页解析器?
正则表达式(模糊匹配),html.parser,BeautifulSoup,lxml(后面三种是一种结构化分析)
结构化解析-DOM(Document Object Model)树
网页解析器--Beautiful Soup语法结构
首先根据下载好的html网页创建BeautifulSoup对象,创建对象的时候就将整个文档字符串加载成一个DOM树
然后根据DOM树进行各种节点的搜索,其中有两个搜索节点方法find_all(搜索出所有满足条件的结果)和find(仅搜索出第一个满足条件的方法),得到节点之后可以访问节点名称,属性,文字。当然,在搜索的时候,可以按照节点的名称,节点的属性,节点的文字进行搜索。
创建BeautifulSoup对象
from bs4 import BeautifulSoup import html.parser #根据HTML网页字符串创建BeautifulSoup对象 soup=BeautifulSoup( html_doc,#HTML文档字符串 'html.parser' #HTML解析器 from_encoding='UTF-8' #HTML文档的编码 )搜索节点(find_all,find)
#方法:find_all(name,attrs,string)
name:节点名称
attrs:节点属性
string:节点内容
#查找所有标签为a的节点
soup.find_all('a')
#查找所有标签为a,链接符合/view/123.html形式的节点
soup.find_all('a',href='/view/123.html')
soup.find_all('a',href=re.compile(r'/view/\d+\.html')#名称和属性我们都可以使用正则表达式来匹配对应内容
#查找所有标签为div,class为abc,文字为python的节点
soup.find_all('div',class_='abc',string='python') #这里类class_有下划线是因为python关键字有class
访问节点信息
#得到节点:<a href='1.html'>python</a>
#获得查找到的节点的标签名称
node.name
#获取的查找到的a节点的href属性
node['href']
#获得查找到的a节点的链接文字
node.get_text()
实战演练:爬取百度百科1000个页面
编写爬虫的过程:
确定目标--分析目标(URL格式,数据格式,网页编码)--编写代码--执行爬虫
目标:百度百科Python词条相关词条网页--标题和简介
入口页:http://baike.baidu.com/link?url=s_o-l76qqBI88DpW3AgRe0kc0m-8DKRUoWyAwPbsY0HzTG9WmXP4RcJA3Uv2VfcMDDGLNPIu0024JBM_U7V-9K
URL格式:
词条页面URL:/view/10598.htm
数据格式:
标题:<dd class="lemmaWgt-lemmaTitle-title"><h1>***</h1></dd>
简介:<div class="lemma-summary">**</div>
页面编码:UTF-8