文章目录
- 一.爬虫简介
- 二.简单爬虫架构
- 三.URL管理器
- 3.1 url管理器应具有的最小功能:
- 3.2 实现方式
- 四.网页下载器
- 4.1 urllib简单的获取一个网页。
- 4.2 使用Request
- 4.3 添加特殊情景的处理
- 五.网页解析器
- 5.1 安装beautifulsoup4
- 5.2 beautifulsoup语法
- 5.3 示例代码:
- 六.完整实例
- 6.1 分析目标
为什么是轻量级爬虫?因为复杂的爬虫需要考虑的场景和问题非常的多,比如有些网页需要登录后才能访问、而有些网页使用javascript异步加载完成。轻量级爬虫爬取的是不需要登录的静态网页抓取。
一.爬虫简介
- 爬虫是一段自动抓取互联网信息的程序,从一个url触发访问所关联的所有url,并且从每个页面中提取出有价值的数据。
- 价值:互联网数据,为我所用。可以对数据进行分析,甚至可以基于数据做出自己的产品,比如更专业的新闻阅读聚合器,最爆笑故事app,最漂亮美女图片网,图书对比价格网,python技术文章大全。
二.简单爬虫架构
首先需要一个爬虫调度端,来启动爬虫、停止爬虫、或者监视爬虫的运行情况。在爬虫架构中有三个模块:
- URL管理器:将要爬取的URL和已经爬取过的URL
- 网页下载器:将网页下载下来存储成一个字符串
- 网页解析器:解析字符串,一方面提取有价值的数据,另一方面提取访问其他页面的URL
三.URL管理器
管理待抓取URL集合和已抓取URL集合,防止重复抓取、循环抓取。
3.1 url管理器应具有的最小功能:
- 添加新url到待爬取集合
- 判断待添加url是否在容器中
- 判断是否还有待爬取url
- 获取待爬取url
- 将url从待爬取移动到已爬取
3.2 实现方式
- 放在内存中set()集合。待爬取set(),已爬取set()
- 存放在关系数据库中urls(url,is_crawled)
- 存放在缓存数据库中,比如redis,本身支持set数据结构。大公司一般都使用缓存数据库
四.网页下载器
将互联网上URL对应的网页下载到本地的工具
- urllib.request:直接的网页下载,或者提交一些向网业输入的数据,甚至支持需要登录网页的cookie处理,需要代理访问的代理处理等。
- requests:第三方包,提供更强大的功能
4.1 urllib简单的获取一个网页。
爬取百度首页就出错。。。试了几种方法,只有(‘gbk’,‘ignore’)有用,并且是偶尔正常显示。爬取其他网页就很顺利,不知道是百度厉害,还是代码太low。最终解决,在第一行添加如下代码即可。。。不过也是是好是坏。
# -*- coding: UTF-8 -*-
或
#coding=utf-8
-
urlopen()参数
- url: 需要打开的网址
- data:Post提交的数据
- timeout:设置网站的访问超时时间,单位秒
-
urlopen返回对象提供方法:
- read() , readline() ,readlines() , fileno() , close() :对HTTPResponse类型数据进行操作
- info():返回HTTPMessage对象,表示远程服务器返回的头信息
- getcode():返回Http状态码。如果是http请求,200请求成功完成;404网址未找到
- geturl():返回请求的url
4.2 使用Request
-
用来包装头部的数据:
- User-Agent :这个头部可以携带如下几条信息:浏览器名和版本号、操作系统名和版本号、默认语言
- Referer:可以用来防止盗链,有一些网站图片显示来源http://***.com,就是检查Referer来鉴定的
- Connection:表示连接状态,记录Session的状态。
4.3 添加特殊情景的处理
HTTPCookieProcessor,ProxyHandler,HTTPHandler,HTTPRedirectHandler生成handler
# -*- coding: UTF-8 -*-
import urllib.request
from http import cookiejar
url = "http://www.baidu.com"
print("第一种方法")
response1 = urllib.request.urlopen(url)
print(response1.getcode())
print(len(response1.read()))
print("第二种方法")
request=urllib.request.Request(url)
request.add_header("user-agent","Mozilla/5.0")
response2=urllib.request.urlopen(request)
print(response2.getcode())
print (len(response2.read()))
print("第三种方法")
cj=cookiejar.CookieJar()
opener=urllib.request.build_opener(urllib.request.HTTPCookieProcessor(cj))
urllib.request.install_opener(opener)
response3=urllib.request.urlopen(url)
print(response3.getcode())
print(cj)
print(response3.read())
五.网页解析器
从网页中提取有价值的数据的工具
- 正则表达式,字符串匹配的模糊匹配,比较直观,但是麻烦
- html.parser自带
- Beautifulsoup插件,结构化解析-DOM树
- lxml插件
5.1 安装beautifulsoup4
可以import bs4即安装成功。查看官方文档
5.2 beautifulsoup语法
创建Beautifulsoup对象,搜索节点find_all、find(参数一样),访问节点名称、属性、文字
例如:
python
节点名称:a
节点属性:href='123.html' class='article_link'
节点内容:python
#创建
soup = BeautifulSoup(html_cont, 'html.parser',from_encoding='utf-8')
#查找节点a
soup.find_all('a')
#查找节点a,链接符合/view/123.html形式的节点
soup.find_all('a',herf='/view/123.html')
soup.find_all('a',herf=re.compile(r'/view/\d+\.html'))#可以用正则表达式替代
#查找节点div,class为abc,文字为python的节点
node = soup.find_all('div',class_='abc', string='python')
#访问节点信息
node.name #标签名称
node['href'] #标签属性
node.get_text() #文字内容
5.3 示例代码:
# coding=utf8
from bs4 import BeautifulSoup
import re
html_doc = """
The Dormouse's story
The Dormouse's story
Once upon a time there were three little sisters; and their names were
Elsie
,
Lacie
and
Tillie
;
and they lived at the bottom of a well.
...
"""
soup = BeautifulSoup(html_doc, 'html.parser')
print("打印所有内容")
links = soup.find_all('a')
for link in links:
print(link.name, link['href'], link.get_text())
print("获取lacie的连接")
link_node = soup.find('a',href="http://example.com/lacie")
print(link_node.name, link_node['href'], link_node.get_text())
print("正则匹配")
link_node = soup.find('a',href=re.compile(r"ill"))
print(link_node.name, link_node['href'], link_node.get_text())
print("获取段落文字")
p_node = soup.find('p',class_="title")
print(p_node.name, p_node.get_text())
六.完整实例
- 目标:抓取百度百科Python词条相关的1000条页面数据。
- 分析目标:URL格式,数据格式,网页编码
- 编写代码
- 最后执行爬虫
6.1 分析目标
- 目标:百度百科python词条相关词条网页-标题和简介
- 入口页:https://baike.baidu.com/item/Python/407313
- url格式:/item/接口/15422203
- 数据格式:
- 标题
...
...
- 简介
...
- 页面编码:UTF-8
查看代码