爬虫不是动物,而是一种计算机程序。
这种程序有自己特定的功能,能按照使用者给定的一系列规则自行浏览万维网并获取需要的信息。此类程序被称为 网络爬虫(web crawler) 或 网络蜘蛛(spider)。
它具有智能分析能力,也称为 机器人程序 。
爬虫的应用应用领域:
如百度、谷歌等以搜索为主的公司,就是利用其自行研发的爬虫程序在互联网上对网页中的数据进行爬取、分析、归类、存储……再提供给用户使用。
新闻聚合应用也是利用爬虫程序爬取各新闻网站上的新闻信息,进行分检归类后提供给使用者。
爬虫程序可运用于各种需要数据分析的应用领域。如价格分析,根据商品关键字爬取各商城中商品价格,对价格进行比较、分析后展示给用户一个直观的对比表。
爬虫程序从网络上爬取数据时,需要遵守 Rebots 协议。
Rebots 协议是网站拟定的资源共享清单,规定爬虫在本网站爬取数据时,哪些资源可以爬取,哪些资源不可以爬取。
爬虫程序的工作流程:
爬虫程序的核心逻辑之一便是通过网络请求模式,下载指定页面的数据。
爬虫程序的本质就是一个网络应用程序。
Python 提供了丰富的库或模块可协助开发者快速开发此类网络应用程序。
urllib 库是 python 内置库,不需要另外安装。完整的 urllib 库包括如下 5 大模块:
使用 urllib.request 模块发送网络请求:
import urllib.request# 基于 https 协议的 url 地址url = "https://www.cnblogs.com/guo-ke/p/15951196.html"# 构建一个请求对象req = urllib.request.Request(url)# 使用 urlopen 方法发送请求包with urllib.request.urlopen(req) as resp: # 解析数据 data = resp.read() print(data.decode())类原型声明:
class Request: def __init__(self, url, data=None, headers={},origin_req_host=None, unverifiable=False,method=None): #…… 其它代码块构造方法参数说明
url:要请求的 url 。
data:data 必须是bytes(字节流)类型,如果是字典,可以用 urllib.parse 模块里的 urlencode( ) 编码
headers:headers 是一个字典类型,用来描述请求头信息。
可在构造方法中指定,也可以通过调用 add_header( ) 方法添加
默认 User-Agent 是 Python-urllib
origin_req_host:指定请求方的 host 名称或者 ip 地址。
unverifiable:设置网页是否需要验证,默认是 False。
method:用来指定请求使用的方法,如 **GET、POST 或 PUT ** 等。
很多网站具有反爬虫设置,除了浏览器之外的访问均认定为非法请求。所以爬虫程序需要把自己伪装成浏览器。
from urllib import request, parseurl = 'http://www.guo-ke.com/post' headers = { # 伪装成谷歌浏览器 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/99.0.4844.51 Safari/537.36', 'Host': 'guo-ke.org'}dict = { 'name': 'guoke', 'key':'python'}# 数据必须是字节流data = bytes(parse.urlencode(dict), encoding='utf8')'''# 转换成 URL 格式的字符串data = parse.urlencode(dict)# 编码成字节流数据data = data.encode()'''request = request.Request(url=url, data=data, headers=headers, method='POST')# req.add_header('User-Agent', 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/99.0.4844.51 Safari/537.36')with request.urlopen(req) as response: res=(response.read() print(res.decode('utf-8'))Tip:当使用了 data 参数或指定 method="POST" 则为POST 请求。
GET 请求也能附加请求参数:https://www.baidu.com/s?wd=java
def urlopen(url, data=None, timeout=socket._GLOBAL_DEFAULT_TIMEOUT, *, cafile=None, capath=None, cadefault=False, context=None):参数说明:
url: 可以接收一个 URL 字符串 或一个 urllib.request.Request 对象。
data: POST 请求的数据,GET 请求设置为 None。
timeout: 设置网站的访问超时时间。仅仅用于使用 HTTP、HTTPS、FTP 协议请求连接时。
cafile、capath: 当使用 HTTPS 请求时,用来指定 CA 数字证书。
cafile 指定数字证书文件。
capath 指定包含的数字认证文件的目录。
返回类型说明:无论使用何种协议发送请求后返回的对象都会包括 3 个通用方法。
geturl( ) 返回请求的资源URL。
info( ) 返回元数据信息,如消息头。
getcode( ) 返回响应的状态码. 如果有错误则会抛出 URLError 异常。
当使用 http 或 https 协议请求后返回的是一个 http.client.HTTPResponse 对象,此对象除了上面的 3 个方法,还包括:
使用 urllib.request 下载一张图片:
爬虫程序强大之处在于能批量、递归下载用户所需要的数据,一个强大的逻辑背后的思想可能就是一个简单的原理支撑的。我们可以先试着下载一张图片以小窥大。
import urllib.request# 图片URLurl = "https://img2022.cnblogs.com/blog/2749732/202202/2749732-20220222195931956-448995015.jpg"with urllib.request.urlopen(url) as resp: data = resp.read() with open("d:/my_file.jpg", "wb") as f: f.write(data)打开对应盘符,可以查阅到图片已经下载成功。
urllib.request 还提供有一个更方便的 urlretrieve( ) 方法。可直接以文件方式存储下载下来的字节流数据。
from urllib import requesturl = "https://img2022.cnblogs.com/blog/2749732/202202/2749732-20220222195931956-448995015.jpg"# urlretrieve() 方法传入的第二个参数为文件保存的位置,以及文件名。request.urlretrieve(url, 'd:/temp.jpg')requests 是基于urllib 编写的第三方库,使用时,需要下载安装:
pip3 install requests主要提供了 2 个方法:
1. get( ) 方法用来发送 GET 请求。
def get(url, params=None, **kwargs): #……参数说明:
基本 GET 使用:
import requests# 用get方式发送请求并获得响应response = requests.get('https://www.cnblogs.com/guo-ke/p/15925214.html')# 用text查看响应内容print(response.text)带参数 get 请求
import requestsresponse = requests.get('https://www.baidu.com/s?wd=java')# 将参数拼接到url后面,用问号分隔,参数间用&来分隔print(response.text)字典格式的参数
import requestsdata = { 'wd': 'java'}response = requests.get('https://www.baidu.com/s', params=data)# 用字典的形式传递给params参数,不需要自己写url编码print(response.text)GET 方法返回一个 Responese 对象,此对象提供有相应属性或方法解析响应包中的数据。
下载一张图片
import requests#;图片地址url = "https://img2022.cnblogs.com/blog/2749732/202202/2749732-20220222195931956-448995015.jpg"#请求头元数据headers = { 'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.181 Safari/537.36'}response = requests.get(url, headers=headers)# 获取字节流数据data = response.content#保存字节流数据with open("d:/test.jpg", "wb") as f: f.write(data)2. post() 方法:以 post 方式发送请求
def post(url, data=None, json=None, **kwargs):参数说明:
基本使用方式
import requestsdata={'name':'zhuzhu','age':'23'}headers={ 'User-Agent':'Mozilla/5.0(Macintosh;Intel Mac OS X 10_11_4)AppleWebKit/537.36(KHTML,like Gecko)Chrome/52.0.2743.116 Safari/537.36'}response=requests.post("http://httpbin.org/post",data=data,headers=headers)#数据必须是json 封装print(response.json())requests 在基于 urllib 编写的第三方库,相比较 urllib 使用起来更简单。对其 API 介绍 ,本文只做了些简单描述。更多方法或使用可查阅文档。