FSA全栈行动 FSA全栈行动
首页
  • 移动端文章

    • Android
    • iOS
    • Flutter
  • 学习笔记

    • 《Kotlin快速入门进阶》笔记
    • 《Flutter从入门到实战》笔记
    • 《Flutter复习》笔记
前端
后端
  • 学习笔记

    • 《深入浅出设计模式Java版》笔记
  • 逆向
  • 分类
  • 标签
  • 归档
  • LinXunFeng
  • GitLqr

公众号:FSA全栈行动

记录学习过程中的知识
首页
  • 移动端文章

    • Android
    • iOS
    • Flutter
  • 学习笔记

    • 《Kotlin快速入门进阶》笔记
    • 《Flutter从入门到实战》笔记
    • 《Flutter复习》笔记
前端
后端
  • 学习笔记

    • 《深入浅出设计模式Java版》笔记
  • 逆向
  • 分类
  • 标签
  • 归档
  • LinXunFeng
  • GitLqr
  • Linux音视频

  • Docker

  • Python环境

  • Python爬虫

    • Python - 爬虫基础与requests模块
      • 一、爬虫基础
        • 1、http 与 https 的概念和区别
        • 2、常见请求头与响应头
        • 3、常见的响应状态码
        • 4、代理
      • 二、requests 模块
        • 1、requests 安装及简单使用
        • 2、Response 响应对象常用属性或方法
        • 3、requests 模块发送请求
    • Python - 爬虫之数据提取
    • Python - 爬虫之Selenium
    • Python - 爬虫之Scrapy
  • 后端
  • Python爬虫
FullStackAction
2021-07-01
目录

Python - 爬虫基础与requests模块

欢迎关注微信公众号:[FSA全栈行动 👋]

# 一、爬虫基础

  • 概念
    • 模拟浏览器,发送请求,获取响应
  • 作用
    • 数据采集
    • 软件测试
    • 抢票
    • 网站上的投票
    • 网络安全

虫师 博客:https://www.cnblogs.com/fnng/ (opens new window)

# 1、http 与 https 的概念和区别

  • HTTP:超文本传输协议,默认端口号是 80。
    • 超文本:指超过文本,不仅限于文本;还包括图片、音频、视频等文件。
    • 传输协议:是指使用共同约定的固定格式来传递转换成字符串的超文本内容。
  • HTTPS:HTTP + SSL(安全套接字层),即带有安全套接字层的超文本传输协议,默认端口号:443。
    • SSL:对传输的内容(超文本,也就是请求体或响应体)进行加密。

结论:HTTPS 比 HTTP 更安全,但是性能要低一点。

# 2、常见请求头与响应头

# 1)请求头

  • Content-Type:内容类型(用于定义网络文件的类型和网页的编码,决定浏览器将以什么形式、什么编码读取这个文件)
  • Host:主机和端口号
  • Connection:链接类型
  • Upgrade-Insecure-Requests:升级为 HTTPS 请求
  • User-Agent:用户代理,提供系统信息和浏览器信息
  • Referer:页面跳转处,常用于防盗链(图片/视频)
  • Cookie:状态保持(有时效性)
  • Authroization:用于表示 HTTP 协议中需要认证资源的认证信息,比如 jwt 认证

注意:加粗的请求头为常用请求头,在服务器被用来进行爬虫识别的频率最高,相较于其余的请求头更为重要。

# 2)响应头

  • Set-Cookie:服务器设置 cookie 到用户浏览器的缓存

# 3、常见的响应状态码

  • 200:成功
  • 302:跳转,新的 url 在响应的 Location 头中给出
  • 303:浏览器对于 POST 的响应进行重定向至新的 url
  • 307:浏览器对于 GET 的响应重定向至新的 url
  • 403:资源不可用;服务器理解客户的请求,但拒绝处理它(没有权限)
  • 404:找不到该页面
  • 500:服务器内部错误
  • 503:服务器由于维护或者负载过重未能应答,在响应中可能会携带 Retry-After 响应头;有可能是因为爬虫频繁访问 url,使服务器忽视爬虫的请求,最终返回 503 响应状态码

注意:所有的状态码都不可信,一切以是否从抓包得到的响应中获取到数据为准。

# 4、代理

# 1)匿名度

根据代理 ip 的匿名程序,代理 IP 可以分为下面三类:

  • 透明代理:透明代理虽然可以直接“隐藏”你的 IP 地址,但还是可以查到你是谁。目标服务器接收到的请求头如下:
REMOTE_ADDR = Proxy IP
HTTP_VIA = Proxy IP
HTTP_X_FORWARDED_FOR = Your IP
  • 匿名代理:使用匿名代理,别人只能知道你用了代理,无法知道你是谁。目标服务器接收到的请求头如下:
REMOTE_ADDR = Proxy IP
HTTP_VIA = Proxy IP
HTTP_X_FORWARDED_FOR = Proxy IP
  • 高匿代理:高匿代理让别人根本无法发现你在使用代理,所以高匿代理是最好的选择。毫无疑问使用高匿代理效果最好。目标服务器接收到的请求头如下:
REMOTE_ADDR = Proxy IP
HTTP_VIA = not determined
HTTP_X_FORWARDED_FOR = not determined

# 2)协议

根据网站所使用的协议不同,需要使用相应协议的代理服务。从代理服务请求使用的协议可以分为:

  • http 代理:目标 url 为 http 协议
  • https 代理:目标 url 为 https 协议
  • socks 隧道代理(例如 socks5 代理)等:
    • socks 代理只是简单地传递数据包,不关心是何种应用协议(FTP、HTTP 和 HTTPS 等)
    • socks 代理比 http、https 代理耗时少
    • socks 代理可以转发 http 和 https 的请求

# 二、requests 模块

  • 作用:发送 http 请求,获取响应数据。

  • 官方文档

    • https://docs.python-requests.org/zh_CN/latest/ (opens new window)
    • 快速上手:https://docs.python-requests.org/zh_CN/latest/user/quickstart.html (opens new window)
    • 高级用法:https://docs.python-requests.org/zh_CN/latest/user/advanced.html (opens new window)
  • 优点(相比于 urllib 模块):

    • requests 模块代码简洁易懂。
    • 使用 requests 编写的爬虫代码将会更少。
    • 功能实现上也简单很多。

# 1、requests 安装及简单使用

# 1)安装

pip/pip3 install requests

# 2)发送 get 请求

import requests

url = 'http://www.baidu.com'

# 向目标url发送get请求
response = requests.get(url)

# print(response.encoding)  # ISO-8859-1

# 打印响应内容(中文可能会乱码)
print(response.text)

注意:response.text 是 requests 模块按照 chardet 模块推测出的编码字符集进行解码的结果。

# 3)字符编码(解决中文乱码)

response.text 和 response.content 的区别:

  • response.text
    • 类型:str
    • 解码类型:requests 模块自动根据 HTTP 头部,对响应的编码作出有根据的推测,推测出文本的编码。
  • response.content
  • 类型:bytes
  • 解码类型:没有指定
# ####### 指定 response.text 编码 #######
# 手动指定编码格式
response.encoding = 'utf8'
print(response.text)

# ####### 指定 response.content 编码 #######
# response.content 是存储的bytes类型的响应源码,可以进行decode操作
# print(response.content.decode('gbk'))
print(response.content.decode())  # 默认utf-8

# 2、Response 响应对象常用属性或方法

  • response.url :响应的 url;有时候响应的 url 和请求的 url 并不一致
  • response.status_code :响应状态码
  • response.request.headers :响应对应的请求头
  • response.headers :响应头
  • response.request._cookies :响应对应请求的 cookie;返回 cookieJar 类型
  • response.cookies :响应的 cookie(经过了 set-cookie 动作;返回 cookieJar 类型)
  • response.json() :自动将 json 字符串类型的响应内容转换为 python 对象(dict or list)
import requests

url = 'http://www.baidu.com'

# 向目标url发送get请求
response = requests.get(url)

# 打印响应内容
# print(response.text)
# print(response.content.decode())
print(response.url)					# 响应的url
print(response.status_code)			# 响应的状态码
print(response.request.headers)		# 响应对象的请求头
print(response.headers)				# 响应头
print(response.request._cookies)	# 请求携带的cookies
print(response.cookies)				# 响应中携带的cookies

# 3、requests 模块发送请求

# 1)发送带请求头的请求

requests.get(url, headers=headers):

  • headers 参数接收字典形式的请求头
  • 请求头字段名为 key,字段对应的值为 value
import requests

url = 'http://www.baidu.com'

# 构建请求头字典
headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.82 Safari/537.36'
}

# 发送带请求头的请求
response = requests.get(url, headers=headers)

print(response.content.decode())

# 2)发送带参数的请求

  • 方式一:在 url 中携带参数,即直接对含有参数的 url 发起请求
  • 方式二:通过 params 携带参数,即构建请求参数字典 data 并设置给 params
    • requests.get(url, params=data)
import requests

headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.82 Safari/537.36'
}

# 方式一:在url中携带参数
# url = 'http://www.baidu.com/s?wd=python'
# response = requests.get(url, headers=headers)

# 方式二:通过params携带参数
url = 'http://www.baidu.com/s'
# 构建参数字典
data = {
    'wd': 'python'
}

response = requests.get(url, headers=headers, params=data)

# 3)发送带 cookie 的请求

  • 方式一:在 headers 参数中携带 cookie
  • 方式二:使用 cookies 参数
    • response = requests.get(url, cookies)
url = 'https://github.com/GitLqr'

# 方式一:在headers参数中携带cookie
# 构建请求头
# headers = {
#     ...,
#     'Cookie': '_octo=GH1.1.1045146750.1615451260; balabala...',
# }
# response = requests.get(url, headers=headers)


# 方式二:使用 cookies 参数(字典)
# 注意:需要字符串 --> 字典
temp = '_octo=GH1.1.1045146750.1615451260; _device_id=cd8d64981fcb3fd4ba7f587873e97804;balabala...'
cookie_list = temp.split('; ')
# 稳妥方案
# cookies = {}
# for cookie in cookie_list:
#     cookies[cookie.split('=')[0]] = cookie.split('=')[-1]
# 推导式方案
cookies = {cookie.split('=')[0]: cookie.split('=')[-1] for cookie in cookie_list}
response = requests.get(url, cookies=cookies)

# 4)cookieJar 对象与字典互转

# cookieJar对象 转换为 cookies字典
dict_cookies = requests.utils.dict_from_cookiejar(response.cookies)

# cookies字典 转换为 cookieJar对象
jar_cookies = requests.utils.cookiejar_from_dict(dict_cookies)

# 5)设置请求超时参数 timeout

requests.get(url, timeout=3):

  • timeout=3 表示:发送请求后,3 秒内返回响应,否则就抛出异常
import requests

url = 'https://twitter.com'

response = requests.get(url, timeout=3)

# 6)proxies 代理参数的使用

response = requests.get(url, proxies=proxies):

  • proxies 类型:字典
import requests

url = 'http://www.baidu.com'

proxies = {
    'http': 'http://61.160.210.234:808',
    'https': 'https://61.160.210.234:808',
}

response = requests.get(url, proxies=proxies)

注意:代理使用成功不会有任何报错,能成功获取响应;如果失败,要么卡滞,要么报错。

  • 免费代理 ip 提供站:
    • http://www.66ip.cn/ (opens new window)
    • https://www.kuaidaili.com/free/ (opens new window)
    • http://www.data5u.com/ (opens new window)
    • http://proxy.mimvp.com/freeopen (opens new window)

# 7)使用 verify 参数忽略 CA 证书

当某些网站的 CA 证书没有经过【受信任的根证书颁发机构】的认证,访问时会被拦截,浏览器会显示【您的连接不是私密连接】等提示,这时有 2 种解决方案:

  • 方式一:下载该网站的 CA 证书,手动导入给当前设备
  • 方式二:使用 response = requests.get(url, verify=False) 直接忽略 CA 证书验证
    • verify 参数能够忽略 CA 证书的认证
import requests

url = 'https://sam.huat.edu.cn:8443/selfservice/'

# 报错:requests.exceptions.SSLError: HTTPSConnectionPool(host='sam.huat.edu.cn', port=8443): Max retries exceeded with url: /selfservice/ (Caused by SSLError(SSLCertVerificationError(1, '[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: self signed certificate (_ssl.c:1125)')))
# response = requests.get(url)

# 警告:InsecureRequestWarning: Unverified HTTPS request is being made to host '127.0.0.1'. Adding certificate verification is strongly advised.
response = requests.get(url, verify=False)

# 8)发送 post 请求

response = requests.post(url, data):

  • data 参数接收一个字典
  • request 模块发送 post 请求函数的其它参数和发送 get 请求的参数完全一致
import requests
import json
import sys


class King(object):
    def __init__(self, word):
        self.url = 'https://ifanyi.iciba.com/index.php?c=trans&m=fy&client=6&auth_user=key_ciba&sign=37218aa29f55fdcc'
        self.headers = {
            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.82 Safari/537.36',
        }
        self.data = {
            'from': 'auto',
            'to': 'auto',
            'q': word
        }

    def get_data(self):
        # 使用post方法发送一个post请求,data为请求体的字典
        response = requests.post(self.url, data=self.data, headers=self.headers)
        return response.content

    def parse_data(self, data):
        # loads方法将json字符串转换成python字典
        dict_data = json.loads(data)
        print(dict_data['content']['out'])

    def run(self):
        response = self.get_data()
        print(response)
        self.parse_data(response)


if __name__ == '__main__':
    # word = input('请输入要翻译的单词或句子:')
    # word = sys.argv[1]
    word = '字典'
    king = King(word=word)
    king.run()

# 9)利用 requests.session 进行状态保持

requests 模块中的 Session 类能够自动处理发送请求获取响应过程中产生的 cookie,进而达到状态保持的目的。

  • 作用:自动处理 cookie
  • 场景:连续的多次请求
  • 使用方法:
session = requests.session() # 实例化session对象
response = session.get(url, headers, ...)
response = session.post(url, data, ...)

注意:session 对象发送 get 或 post 请求的参数,与 requests 模块发送请求的参数完全一致

#Python爬虫#requests
Mac上pyenv的安装与使用
Python - 爬虫之数据提取

← Mac上pyenv的安装与使用 Python - 爬虫之数据提取→

最近更新
01
Flutter - Xcode16 还原编译速度
04-05
02
AI - 免费的 Cursor 平替方案
03-30
03
Android - 2025年安卓真的闭源了吗
03-28
更多文章>
Theme by Vdoing | Copyright © 2020-2025 FSA全栈行动
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式
×