定义:网络爬虫,是一种按照一定规则,自动爬取互联网信息的程序和脚本。用于模拟人操作浏览器打开网页,获取网页中的指定数据。
爬虫的种类 | 作用 |
---|---|
通用爬虫 | 爬取网页页面全部的源码数据 |
聚焦爬虫 | 爬取网页页面中的局部数据 |
增量式爬虫 | 用来检测网站数据的更新情况,一遍爬取到网站最新更新的数据 |
分布式爬虫 | 多人爬取,提高网站数据的爬取数据 |
第一个:根据爬取的数量不同进行分类:
①通用爬虫:通常指搜索引擎的爬虫。
通用爬虫是搜索引擎抓取系统 (baidu,goole,yahoo等)的重要组成部分 。主要目的是将互联网的网页下载到本地 ,形成一个互联网内容的镜像备份。(但是有一个很大的问题就是它们具有很大的局限性:大部分内容没有用——不同的搜索目的,返回的内容相同!)
②聚焦爬虫:针对特定网站的爬虫。
是面向特定主题需求的一种网络爬虫程序 ,它与通用搜索引擎爬虫的区别在于 :
聚焦爬虫在实施页面抓取时会对内容进行处理筛选,尽量保证只抓取与需求相关的网页信息!
多页面爬取:目标网站的分析【利用开发者工具】 - > 发起请求【检查–网络Network
– 标头Agent
,找到相对应的URL】 -> 获取响应 – > 继续发起请求 – > 获得响应,进行解析 -> 保存数据。
我们在浏览器中,经常涉及到数据的交换,比如你登录邮箱,登录一个页面。我们经常会在此时设置30天内记住我,或者自动登录选项。那么它们是怎么记录信息的呢,答案就是cookie,Cookie是由HTTP服务器设置的,保存在浏览器中,但HTTP协议是一种无状态协议,在数据交换完毕后,服务器端和客户端的链接就会关闭,每次交换数据都需要建立新的链接。
Cookie是一种存储在用户计算机或移动设备中的小文本文件,用于跟踪用户在网站上的活动和状态。当您访问一个网站时,该网站会向您的计算机发送一个Cookie。
Cookie包含有关您的访问信息,如您的浏览器类型,操作系统,语言偏好和其他访问信息。
Cookie可以用于记录您的登录状态,以便您在下一次访问网站时不必再次输入用户名和密码。它们也可以用于跟踪您的浏览历史记录,以便网站可以提供更加个性化的内容和广告。但是,Cookie也可能被用于跟踪您的隐私信息和活动,这可能会引起隐私和安全方面的问题。因此,大多数浏览器都提供了选项来允许您控制Cookie的使用和删除Cookie。
F12
打开浏览器开发者工具,然后按如图步骤即为Cookies
:
Request headers
(请求头)是在客户端向服务器发出HTTP请求时,包含在请求中的元数据。这些元数据包含有关请求的信息,如请求的类型(GET,POST等)、请求的来源、请求的内容类型、请求的时间戳等。
Request headers通常包含在HTTP请求的头部,以键值对的形式表示。例如,User-Agent表示浏览器的类型和版本,Accept表示客户端支持的MIME类型,Referer表示请求来源页面的URL地址等。
Request headers是HTTP协议中非常重要的一部分,它们提供了关于请求的附加信息,从而帮助服务器理解请求的目的和内容,并做出相应的响应。同时,request headers也可以用于控制缓存、认证和安全等方面的操作。
User-Agent
是一个HTTP请求头的字段,它包含了发送请求的客户端(通常是浏览器)的相关信息,例如浏览器类型、版本号、操作系统、设备类型等等。
Web服务器可以使用User-Agent头来确定客户端使用的软件和硬件环境,从而提供更适合的响应。例如,网站可能会根据User-Agent头来确定如何渲染页面、提供适当的内容或响应不同类型的设备。
注意:User-Agent头信息可以通过JavaScript或后端代码获取,因此一些网站可能会使用这些信息来分析访问者的行为、统计浏览器市场份额等信息。所以这也给了我们爬虫的可乘之机。
用户也可以通过修改User-Agent头来隐藏自己的身份或欺骗服务器,因此User-Agent并不能完全确定访问者的真实身份。
通常我们在练习爬虫代码的时候,就需要使用自己实际访问的User-Agent,到后面可以使用代理。
Referrer
是指从哪个页面链接到当前页面的URL地址,通常用于追踪和分析网站的流量来源。当用户点击链接或通过搜索引擎访问网站时,Referrer字段将包含来源页面的URL地址。
Referrer信息通常由Web浏览器发送,它可以告诉Web服务器访问者从哪个页面链接到当前页面。
这个信息对于网站管理员来说很有用,因为它可以让他们了解网站的流量来源和用户行为。
然而,由于Referrer信息可以包含一些敏感信息,如搜索关键词或上一个访问页面的URL地址,因此有些浏览器和网络安全软件可能会禁止发送Referrer信息,或者在发送时对其进行过滤或匿名化。
在学习爬虫的时候,了解HTTP是非常重要的,因为HTTP是Web应用程序使用的基础协议。HTTP(Hypertext Transfer Protocol)是一种用于传输超文本(包括HTML文件、图像、音频、视频、样式表等)的应用层协议。
当使用爬虫抓取网站数据时,爬虫首先需要发送HTTP请求,然后从服务器接收HTTP响应。爬虫使用HTTP来与Web服务器通信,HTTP指示了数据如何传输和呈现。因此,了解HTTP协议的基础知识对于学习爬虫是至关重要的。
HTTP状态码的第一位数字定义了状态码的类型,通常有以下五种类型:
状态码 | 解释说明 |
---|---|
1xx | 信息性状态码,表示请求已被接收,继续处理。 |
2xx | 成功状态码,表示请求已成功被服务器接收、理解、并接受。 |
3xx | 重定向状态码,表示需要客户端进一步操作才能完成请求。 |
4xx | 客户端错误状态码,表示客户端发起的请求存在问题,请求未能被服务器理解或接受。 |
5xx | 服务器错误状态码,表示服务器在处理请求时发生错误。 |
是一个简洁且简单地处理HTTP请求的第三方库,他最大的优点是从程序编写过程更接近正常的URL访问过程。
官方教学文档如下:
https://requests.readthedocs.io/projects/cn/zh_CN/latest/
第三方库的下载: 打开python
下的cmd
,pip install + 第三方库名
第三方库的导入: import
requests
构造并返回 Request对象:
r = requests.get(url)
Response对象包含服务器返回的所有信息,也包含请求的Request信息。
属性如下:
属性 | 说明 |
---|---|
r.status_code | HTTP请求返回的状态,200表示成功,404表示失败 |
r.text | HTTP响应的字符串 形式,url对应的页面内容 |
r.content | HTTP响应内容的二进制 形式(图片、视频、音频) |
注意:
- 如果图片文件存入了js里面,解码需要导入json库,利用
json.loads()
进行解码,构成所需数据框,不然源代码是一串字符串,无法进行之后的操作- 编码所用函数:导入
from urllib import parse
,使用parse.quote()
进行编码
cookies
:import requests
from fake_useragent import UserAgent
r = requests.get(url,headers = headers)
# 方法一,items打印出列表形式,遍历后依次打印
for key,value in r.cookies.items():
print(key + "=" + value)
# 方法二,转换为字典形式
cookie = requests.utils.dict_from_cookiejar(r.cookies)
print(cookie)
获取headers
,可以使用r.headers
获取发送请求后响应的url
,可以使用r.url
requests.get()
和 requests.post()
是 Python 中的两个常用的 HTTP 请求库,可以用于发送 GET 和 POST 请求。这两个函数都可以接受多个参数,下面是对它们常用参数的详细解释:
对于 requests.get(url, params=None, **kwargs)
函数:
1、设置cookie
,上述已经讲过获取的方法。
2、设置代理proxies
提示:知不知道服务器的地址做为判断标准:知道就是正向代理,不知道就是反向代理。
我们为什么要使用代理?
(1)让服务器以为不是同一个客户端在请求;
(2)防止我们的真实地址被泄露,防止被追究。
用法:
当我们需要使用代理时,同样构造代理字典,传递给proxies参数。
3、禁止证书验证vertify
有时候我们使用了抓包工具,这个时候由于抓包工具提供的证书并不是由受信任的数字证书颁发机构颁发的,证书的验证就会失败,这时我们就需要关闭证书验证false。
(3)设置timeout
实际上,我们在多数爬虫开发中——超时参数timeout是和retrying模块(刷新)一起使用的!
代码转载自一位大神:点此跳转
import requests
from retrying import retry
headers = {"User-Agent":"Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US) AppleWebKit/532.2 (KHTML, like Gecko) Chrome/4.0.222.3 "}
@retry(stop_max_attempt_number=3) # stop_max_attempt_number=3最大执行3次,还不成功就报错
def _parse_url(url): # 前面加_代表此函数,其他地方不可调用
print("*"*100)
response = requests.get(url, headers=headers, timeout=3) # timeout=3超时参数,3s内
assert response.status_code == 200 # assert断言,此处断言状态码是200,不是则报错
return response.content.decode()
def parse_url(url):
try:
html_str = _parse_url(url)
except Exception as e:
print(e)
html_str = None
return html_str
if __name__ == '__main__':
# url = "www.baidu.com" # 这样是会报错的!
url = "http://www.baidu.com"
print(parse_url(url))
对于 requests.post(url, data=None, json=None, **kwargs) 函数:
Content-Type
在HTTP的请求正文里面,和POST提交数据方式的关系如下图:
Content-Type | 提交数据的方式 |
---|---|
application/x-www-form-urlencoded | 表单数据 |
multipart/form-data | 表单文件上传 |
application/json | 序列化JSON数据 |
text/xml | XML数据 |
在爬取代码的时候,一定要找对HTTP的请求,构建正确POST请求,否则无法返回相应的内容。
更详细的信息和更多参数可以在官方文档中查看:
- requests.get(): https://docs.python-requests.org/en/latest/api/#requests.get
- requests.post(): https://docs.python-requests.org/en/latest/api/#requests.post
在 Python 的 requests 库中,data
和 params
都是用于向服务器发送请求的参数,但它们的作用和使用场景略有不同。
params
通常用于发送 GET 请求时,用于传递查询字符串参数。查询字符串是在 URL 中出现的键值对,它们被包含在 URL 的问号(?)后面,多个键值对之间使用 & 符号分隔。例如,假设我们要发送一个 GET 请求到 https://example.com/search,查询字符串中包含 q
和 page
两个参数,可以这样写:
import requests
params = {'q': 'python', 'page': '2'}
response = requests.get('https://example.com/search', params=params)
发送请求后,requests 库将自动将 params 中的参数编码到 URL 的查询字符串中,得到的完整 URL 是 https://example.com/search?q=python&page=2。
data
则通常用于发送 POST 请求时,用于传递表单数据、JSON 数据等请求体参数。它们以字典的形式传递给 data 参数,然后 requests 库会将其编码为适当的格式发送给服务器。例如,假设我们要发送一个 POST 请求到 https://example.com/login,包含用户名和密码两个表单字段,可以这样写:
import requests
data = {'username': 'alice', 'password': 'secret'}
response = requests.post('https://example.com/login', data=data)
发送请求后,requests 库将自动将 data 中的参数编码为 application/x-www-form-urlencoded 或 multipart/form-data 格式,作为请求体发送给服务器。
需要注意的是,虽然
params
和data
在作用和使用场景上略有不同,但它们都是可选参数,可以根据实际情况选择使用或不使用。
r.text
,获得url返回的内容。
r.josn
如果我们访问之后获得的数据是JSON格式的,那么我们可以使用json()方法,直接获取转换成字典格式的数据。之后,利用json.loads()
进行解码。
知识点一:
有时候我们会遇到相同的url参数名,但有不同的值,而python的字典又不支持键的重名,那么我们可以把键的值用列表表示:
import requests
params = {'key': 'value1', 'key2': ['value2', 'value3']}
resp = requests.get("http://httpbin.org/get", params=params)
print(resp.url)
知识点二:
注意:json和data二者只能同时存在其一
爬虫难点主要分为两个方向:
注意:域名可以确定是哪一台电脑;而端口号是为了确定是那台电脑的哪一个应用
re.findall(b"From Inner Cluster \r\n\r\n(.*?)",first_data,re.s)
这串代码是什么意思
解释:
1、该正则表达式的作用是从first_data
字符串中找到所有以"From Inner Cluster"开头,后跟两个回车符(\r\n\r\n),然后是任何字符的子字符串,并返回一个列表。
2、re.s
标志被用于 re.findall() 方法的第三个参数中,以表示该正则表达式模式中的 . 可以匹配包括换行符在内的任何字符。