爬虫随笔—概述与get请求
一:爬虫概述
(一):定义
网络爬虫是一种按照一定的规则,自动去抓取万维网信息的程序或者脚本。简单的说就是用事先写好的程序去抓取网络上所需的数据,这样的程序就叫网络爬虫。
(二):爬虫分类
-
通用爬虫
通用网络爬虫是搜索引擎抓取系统(Baidu, Google, Yahoo等)的重要组成部分。主要目的是将互联网上的网页下载到本地,形成一个互联网内容的镜像备份。
缺点:
(1). 通用搜索引擎返回的结果都是网页,而大多数情况下,网页里90%的内容对用户来说都是无用的
(2). 不同领域,不同背景的用户往往具有不同的检索目的和需求,搜索引擎无法提供针对具体某个用户的搜索结果
(3). 万维网数据形式的丰富和网络技术的不断发展,图片、数据库、音频、视频多媒体等不同数据大量出现,通用搜索引擎对这些文件无能为力,不能很好的发现和获取
(4). 通用搜索引擎大多提供基于关键字的检索,难以支持根据语义信息提出的查询,无法准确理解用户的具体需求
针对这些情况,聚焦爬虫技术得以广泛应用。
-
聚焦爬虫
聚焦爬虫,是“面向特定主题需求”的一种网络爬虫程序,它与通用搜索引擎爬虫的区别在于:聚焦爬虫在实施网页抓取时会对内容进行处理筛选,尽量保证只抓取与需求相关的网页信息。我们今后的笔记都是有关聚焦爬虫的。
三:request模块
-
requests模块简介
Urllib和Resquests模块是发起http请求最常见的模块。Resquests相当于Urllib的改进版,相比与Urllib来说,Request更加的简洁方便,支持cookie保持会话,支持文件上传,支持自动确定响应内容的编码,支持国际化的URL和POST数据自动编码。Resquests的底层实现其实就是urllib3(urllib的升级版)。
使用时只需安装requests模块即可
pip install requests
-
requests模块get请求
客户端发送一个请求,服务器收到这个请求后就会将请求所对应的响应返回给客户端,客户端收到这个响应将其显示出来。我们使用requests模块其实就是在模仿客户端和服务器的这个过程。
(1). get请求中无参数
# 将请求的返回值(即响应)赋给变量response response = requests.get( url = "请求页面的url", headers = 请求头, params = 请求参数字典 ) # response对象的属性 print(response.url) # 查看响应的url print(response.text) # 获取页面内容(字符串) print(response.content) # 获取页面二进制类型内容 print(response.content.decode()) # 将二进制内容按指定格式进行解码 print(response.response.headers) # 获取响应头 print(response.status_code) # 获取响应状态码
text与content的区别:
- text获取页面文本类型数据,在大部分使用text获取数据时都不会出现乱码情况,如果出现乱码情况,使用content.decode()解决乱码
- content()获取页面二进制类型的内容,在下载图片、视频、音频等媒体文件时必须使用content()
案例一:将百度产品大全页面保存到本地
# 需求:将百度产品大全页面保存到本地
# 爬虫就是在模拟认为的操作
# 导入requests模块
import requests
# 发送请求,返回响应
# 确定请求的url:https://www.baidu.com/more/
# 这里,我们先以get请求举例
# 什么请求方式,就调用什么方法,get请求需要调用resquests的get`方法
response = requests.get(url="https://www.baidu.com/more/")
# print(response) # 返回结果为 <Response [200]>
# text:获取页面文本类型(字符串)内容,在注释处出现了汉字乱码问题
print(response.text)
# 解决方案:使用response对象的content方法获取二进制页面内容,然后再进行解码
# decode()可以加参数,默认为utf-8编码
# 大部分网页都是使用utf-8或者是gbk,这两种编码格式基本上可以解决所有编码错误
print(response.content.decode())
# 如果仍存在编码错误,则可先获取响应对象的编码格式,然后在指定解码格式
# de_style = response.encoding # 获取编码格式
# print(response.content.decode(de_style))
# 保存文件
with open("baidu.html", "w", encoding="utf8") as f:
f.write(response.content.decode())
# 保存图片,与保存页面相似,仅仅是把response的text方法改为content方法
img_response = requests.get(
url="https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1605801401532&di=524f3633b0b0f650f9a49f237941e403&imgtype=0&src=http%3A%2F%2Fa4.att.hudong.com%2F22%2F59%2F19300001325156131228593878903.jpg"
)
with open("erha.jpg", "wb") as f:
f.write(img_response.content)
(2):发送请求,获取响应,get请求中有参数
# 需求:将新浪搜索python的页面保存至本地
import requests
# 原完整url="http://search.sina.com.cn/?q=python&c=news&from=index"
# 提取参数:在请求时传入参数params,接受字典类型数据
# params作用:自动的将参数按照地址栏的参数形式拼接,?会自动添加
# 定义字典参数
params = {
"q":"python",
"c":"news",
"from":"index"
}
# get请求的参数是放在Query String Parameters中
# get请求时,传递的关键字参数是params
response = requests.get(
url="http://search.sina.com.cn/",
params=params
)
# 查看响应的url地址
print(response.url)
# 查看页面源代码
print(response.text)
# 保存
with open("xinlang.html", "w", encoding="utf8") as f:
f.write(response.text)
# 发现问题:保存的html文件没有乱码,但是在浏览器中打开却乱码了
# 原因:浏览器的问题,
# 解决方法:
# 在浏览器中下载可进行转码的插件
# print(response.encoding),得到html页面的编码格式
# 将浏览器中的编码格式选为和html页面相同的编码格式
(3):get请求自定义搜索内容
# 需求:自定义搜索内容
import requests
# 原url="https://www.baidu.com/s?ie=utf-8&f=8&rsv_bp=1&rsv_idx=1&tn=baidu&wd=python%20&fenlei=256&rsv_pq=af44a1b100048f4a&rsv_t=c069lGltj3B68r4fSYJeTk2t48ZBLW%2BG35pO2UbRDUtuubY2HTiCILmCjzQ&rqlang=cn&rsv_enter=1&rsv_dl=ib&rsv_sug3=9&rsv_sug1=20&rsv_sug7=101&rsv_sug2=0&rsv_btype=i&inputT=6176&rsv_sug4=7707"
# 首先对url进行修剪,将无用的get请求参数全部去掉
# 方法:在浏览器的网址中一个一个的删除,对页面展示没有影响的参数都删掉
# 删除后的url="https://www.baidu.com/s?wd=python"
# 自定义搜索内容需要遵循一定的规律
wd = input("请输入要查询的内容:")
# 定义请求头字典
headers = {
"User-Agent": "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:82.0) Gecko/20100101 Firefox/82.0"
}
# 注意:
# 1. 以后不管写什么爬虫,都加上请求头,至少加一个UA
# 2. 如果加入UA之后还是访问不到数据,尝试加入cookie
# 3. 如果加入cookie还不好使,就将全部的请求头都加入,以:开头的请求头不要加入
params = {
"wd": wd
}
response = requests.get(
url="https://www.baidu.com/s", # url中一般写url中固定不变的内容
params = params,
headers = headers
)
print(response.url)
# 保存文件
with open("baidu_inp.html", "w", encoding="utf8") as f:
f.write(response.text)
# 发现错误:返回的内容和网页源代码相差很远
# 查看默认请求头
# 从结果可以看出,请求是由python发出的,所以反爬机制做了处理
print(response.request.headers)
# 解决方法:加上请求头
(4). get请求,一次爬取多个页面
# 需求:获取虎扑新闻前五页的新闻
import requests
# 虎扑前五条新闻的url
# https://voice.hupu.com/news?category=all&page=1
# https://voice.hupu.com/news?category=all&page=2
# https://voice.hupu.com/news?category=all&page=3
# https://voice.hupu.com/news?category=all&page=4
# https://voice.hupu.com/news?category=all&page=5
# 可发现随着页数的不同只有page的数值发生了改变
headers = {
"User-Agent": "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:82.0) Gecko/20100101 Firefox/82.0"
}
params = {
"category": "all"
}
for page in range(1, 6):
params["page"]=page
response = requests.get(
url="https://voice.hupu.com/news",
headers=headers,
params=params
)
print(response.url)
# 保存时需要使每个文件的名字不同,不然会覆盖
with open(f"mant_html{page}.html", "w", encoding="utf8") as f:
f.write(response.text)