Python-Requests与BeautifulSoup实战

Requests 基本使用库

Python 提供了多个用来编写爬虫程序的库,有一个重要网络请求库就是 Requests 库,这个库的宗旨是"让 HTTP 服务于人类"。

Requests 是 Python 的第三方库,它的安装非常简便,如下所示:

复制代码
pip install requests

Requests 库是在 urllib 的基础上开发而来,它使用 Python 语言编写,并且采用了 Apache2 Licensed(一种开源协议)的 HTTP 库。与 urllib 相比,Requests 更加方便、快捷,因此在编写爬虫程序时 Requests 库使用较多,接下来我们一起来学习requests库。

常用请求方法

requests.get()

该方法用于 GET 请求,表示向网站发起请求,获取页面响应对象。语法如下:

复制代码
res = requests.get(url, headers=headers, params, timeout)

参数说明如下:

  • url:要抓取的 url 地址。
  • headers:用于包装请求头信息。
  • params:请求时携带的查询字符串参数。
  • timeout:超时时间,超过时间会抛出异常。

具体使用示比如下:

python 复制代码
import requests
url = 'http://baidu.com'
response = requests.get(url)
print(response)
# print(response.text)  可以查看请求具体的返回数据信息

输出结果:

复制代码
<Response [200]>

200 是请求返回状态码,表示请求成功。

如果我们想要请求时带上请求参数,使用也非常的简单,这里使用到了 http://httpbin.org,当我们请求http://httpbin.org/get 时会返回具体的请求信息,示比如下所示:

python 复制代码
import requests
data = {'name': '渣男教父', 'url': "www.ybf.com"}
response = requests.get('http://httpbin.org/get', params=data)  # 直接拼接参数也可以
# response = requests.get('http://httpbin.org/get?name=ybf&age=33')
# 调用响应对象text属性,获取文本信息
print(response.text)

输出结果:

python 复制代码
{
  "args": {
    "name": "\u6709\u9738\u592b",
    "url": "www.ybf.com"
  },
  "headers": {
    "Accept": "*/*",
    "Accept-Encoding": "gzip, deflate",
    "Host": "httpbin.org",
    "User-Agent": "python-requests/2.25.1",
    "X-Amzn-Trace-Id": "Root=1-62216f84-2054fe065f625d4928c77cfa"
  },
  "origin": "175.0.53.160",
  "url": "http://httpbin.org/get?name=\u6709\u9738\u592b&url=www.ybf.com"
}
requests.post()

该方法用于 POST 请求,先由用户向目标 url 提交数据,然后服务器返回一个 HttpResponse 响应对象,语法如下:

复制代码
response = requests.post(url, data={请求体的字典})

示比如下所示:

python 复制代码
import requests
url = 'https://fanyi.baidu.com'  # 百度翻译
# post请求体携带的参数,可通过开发者调试工具查看
# 查看步骤:NetWork选项->Headers选项->Form Data
data = {'from': 'zh', 'to': 'en', 'query': '欢迎参加跟渣男教父学编程课堂'}
response = requests.post(url, data=data)
print(response)
# print(response.text)  可以查看请求具体的返回数据信息

输出结果:

复制代码
<Response [200]>

chrome中查看 Form Data 的步骤非常的简单,如下图所示:

响应对象属性

当我们使用 Requests 模块向一个 URL 发起请求后会返回一个 HttpResponse 响应对象,该对象具有以下常用属性:

常用属性 说明
encoding 查看或者指定响应字符编码
status_code 返回HTTP响应码
url 查看请求的 url 地址
headers 查看请求头信息
cookies 查看cookies 信息
text 以字符串形式输出
content 以字节流形式输出,若要保存下载图片需使用该属性。

使用示比如下所示:

python 复制代码
import requests
response = requests.get('http://www.baidu.com')
print(response.encoding)
response.encoding = "utf-8"  # 更改为utf-8编码
print(response.status_code)  # 打印状态码
print(response.url)          # 打印请求url
print(response.headers)      # 打印头信息
print(response.cookies)      # 打印cookie信息
print(response.text)         # 以字符串形式打印网页源码
print(response.content)      # 以字节流形式打印

输出结果:

复制代码
# 编码格式
ISO-8859-1
# 响应码
200
# url地址
http://www.baidu.com/
# 请求头信息
{'Cache-Control': 'private, no-cache, no-store, proxy-revalidate, no-transform', 'Connection': 'keep-alive', 'Content-Encoding': 'gzip', 'Content-Type': 'text/html', 'Date': 'Fri, 04 Mar 2022 02:04:36 GMT', 'Last-Modified': 'Mon, 23 Jan 2017 13:27:57 GMT', 'Pragma': 'no-cache', 'Server': 'bfe/1.0.8.18', 'Set-Cookie': 'BDORZ=27315; max-age=86400; domain=.baidu.com; path=/', 'Transfer-Encoding': 'chunked'}
# 查看cookies信息
<RequestsCookieJar[<Cookie BDORZ=27315 for .baidu.com/>]>
...内容过长,此处省略后两项输出

在使用 requests请求网页时,我们可以很方便的拿到响应对象的各种信息,实际使用中可以很灵活的进行操作。

实用请求参数

SSL认证-verify参数

SSL 证书是数字证书的一种,类似于驾驶证、护照和营业执照。因为配置在服务器上,也称为 SSL 服务器证书。SSL 证书遵守 SSL 协议,由受信任的数字证书颁发机构 CA(电子认证服务)颁发。 SSL 具有服务器身份验证和数据传输加密功能。

verify 参数的作用是检查 SSL 证书认证,参数的默认值为 True,如果设置为 False 则表示不检查 SSL证书,此参数适用于没有经过 CA 机构认证的 HTTPS 类型的网站。其使用格式如下:

复制代码
response = requests.get(url=url, params=params, headers=headers, verify=False)
代理IP-proxies参数

一些网站为了限制爬虫从而设置了很多反爬策略,其中一项就是针对 IP 地址设置的。比如,访问网站超过规定次数导致流量异常,或者某个时间段内频繁地更换浏览器访问,存在上述行为的 IP 极有可能被网站封杀掉。

代理 IP 就是解决上述问题的,它突破了 IP 地址的访问限制,隐藏了本地网络的真实 IP,而使用第三方 IP 代替自己去访问网站。

1. 代理IP池

通过构建代理 IP 池可以让你编写的爬虫程序更加稳定,从 IP 池中随机选择一个 IP 去访问网站,而不使用固定的真实 IP。总之将爬虫程序伪装的越像人,它就越不容易被网站封杀。当然代理 IP 也不是完全不能被察觉,通过端口探测技等术识仍然可以辨别。其实爬虫与反爬虫永远相互斗争的,就看谁的技术更加厉害。

2. proxies参数

Requests 提供了一个代理 IP 参数proxies ,该参数的语法结构如下:

复制代码
proxies = {
    '协议类型(http/https)': '协议类型://IP地址:端口号'
}

下面构建了两个协议版本的代理 IP,示比如下:

复制代码
proxies = {
    'http': 'http://IP:端口号',
    'https': 'https://IP:端口号'
}

3. 代理IP使用

下面通过简单演示如何使用proxies 参数,示比如下:

python 复制代码
import requests
url = 'http://httpbin.org/get'
headers = {'User-Agent': 'Mozilla/5.0'}
proxies = {'http': 'http://1.194.238.242:3828'}  # 网上找的免费代理ip
html = requests.get(url, proxies=proxies, headers=headers, timeout=10).text
print(html)

输出结果:

html 复制代码
{
  "args": {},
  "headers": {
    "Accept": "*/*",
    "Accept-Encoding": "gzip, deflate",
    "Cache-Control": "max-age=259200",
    "Host": "httpbin.org",
    "User-Agent": "Mozilla/5.0",
    "X-Amzn-Trace-Id": "Root=1-622b1032-3ef292bc349cd9ca3d57e39f"
  },
  "origin": "1.194.238.242",
  "url": "http://httpbin.org/get"
}

由于上述示例使用的是免费代理 IP,因此其质量、稳定性较差,可能会随时失效。如果想构建一个稳定的代理 IP 池,就需要花费成本。

4. 付费代理IP

网上有许多提供代理 IP 服务的网站,比如快代理、携趣代理等。这些网站也提供了相关文档说明,以及 API 接口,爬虫程序通过访问 API 接口,就可以构建自己的代理 IP 池。

付费代理 IP 按照资源类型可划分为:开发代理、私密代理、隧道代理、独享代理,其中最常使用的是开放代理与私密代理。

  • 开放代理:开放代理是从公网收集的代理服务器,具有 IP 数量大,使用成本低的特点,全年超过 80% 的时间都能有 3000 个以上的代理 IP 可供提取使用。
  • 私密代理:私密代理是基于云主机构建的高品质代理服务器,为您提供高速、可信赖的网络代理服务。私密代理每天可用 IP 数量超过 20 万个,可用率在 95 %以上,1 次可提取 IP 数量超过 700 个,可以为爬虫业务提供强大的助力。

付费代理的收费标准根据 IP 使用的时间长短,以及 IP 的质量高低,从几元到几百元不等,网上有很多提供免费代理 IP 的网站,不过想找到一个质量较高的免费代理好比大海捞针。

用户认证-auth参数

Requests 提供了一个auth 参数,该参数的支持用户认证功能,也就是适合那些需要验证用户名、密码的网站。auth 的参数形式是一个元组,其格式如下:

复制代码
auth = ('username', 'password')

其使用示比如下所示:

python 复制代码
import requests  # 导入requests模块
# 定义请求地址
url = 'http://sck.rjkflm.com:666/spider/auth/'
ah = ('admin', 'admin')
response = requests.get(url=url, auth=ah)
if response.status_code == 200:
    print(response.text)

Requests 库实战应用

接下来我们学习使用 Requests 库下载图片。

首先打开天堂图片网(https://www.ivsky.com/),然后使用 Chrome 开发者工具随意查看一张图片的源地址,如下图所示:

图片地址为:

html 复制代码
<img src="//img.ivsky.com/img/tupian/slides/202109/09/xiniu-001.jpg">

可以将上述 url 粘贴至浏览器地址栏进行验证。当我们确定图片地址后,就可以使用 requests 库进行编码了:

python 复制代码
import requests
url = 'https://img.ivsky.com/img/tupian/slides/202109/09/xiniu-001.jpg'
headers = {'User-Agent': 'Mozilla/4.0'}
html = requests.get(url=url, headers=headers).content  # 读取图片需要使用content属性
with open('D:/requests_img.jpg', 'wb') as f:  # 以二进制的方式下载图片
    f.write(html)

最后,在D盘目录下可以找到已经下载好的图片。

网页解析 BeautifulSoup 库

BeautifulSoup 简称 BS4(其中 4 表示版本号)是一个 Python 第三方库,它可以从 HTML 或 XML 文档中快速地提取指定的数据。Beautiful Soup 语法简单,使用方便,并且容易理解,可以快速地学习并掌握它。

下面我们讲解 BS4 的基本语法。

由于 BeautifulSoup 是第三方库,因此需要单独下载,下载方式非常简单,执行以下命令即可安装:

复制代码
pip install bs4

由于 BS4 解析页面时需要依赖文档解析器,所以还需要安装 lxml 作为解析库:

复制代码
pip install lxml

Python 也自带了一个文档解析库 html.parser,但是其解析速度要稍慢于 lxml。除了上述解析器外,还可以使用 html5lib 解析器,安装方式如下:

复制代码
pip install html5lib

该解析器生成 HTML 格式的文档,但速度较慢。

BS4解析对象

创建 BS4 解析对象是万事开头的第一步,这非常地简单,语法格式如下所示:

python 复制代码
# 导入解析包
from bs4 import BeautifulSoup
# 创建beautifulsoup解析对象
soup = BeautifulSoup(html_doc, 'html.parser')

上述代码中,html_doc 表示要解析的文档,而 html.parser 表示解析文档时所用的解析器,此处的解析器也可以是 'lxml' 或者 'html5lib',示例代码如下所示:

python 复制代码
# -*- coding: UTF-8 -*-
from bs4 import BeautifulSoup
html_doc = """<html><head><title>"跟渣男教父学编程"</title></head><body><p class="title"><b>www.youbafu.com</b></p><p class="website">跟渣男教父学编程<a href="http://youbafu.com/python/" id="link1">python教程</a><a href="http://youbafu.com/c/" id="link2">c语言教程</a>"""
soup = BeautifulSoup(html_doc, 'html.parser')
# prettify()用于格式化输出html/xml文档
print(soup.prettify())

输出结果:

html 复制代码
<html>
 <head>
  <title>
   "跟渣男教父学编程"
  </title>
 </head>
 <body>
  <p class="title">
   <b>
    www.youbafu.com
   </b>
  </p>
  <p class="website">
   跟渣男教父学编程
   <a href="http://youbafu.com/python/" id="link1">
    python教程
   </a>
   <a href="http://youbafu.com/c/" id="link2">
    c语言教程
   </a>
  </p>
 </body>
</html>

如果是外部文档,您也可以通过 open() 的方式打开读取,语法格式如下:

复制代码
soup = BeautifulSoup(open('html_doc.html', encoding='utf8'), 'lxml')

BS4常用语法

接下来一起学习一下爬虫中经常用到的 BS4 解析方法。

Beautiful Soup 将 HTML 文档转换成一个树形结构,该结构有利于快速地遍历和搜索 HTML 文档。下面使用树状结构来描述一段 HTML 文档:

html 复制代码
<html>
    <head><title>跟渣男教父学编程</title></head>
    <body>
        <h1>www.bpsend.net</h1>
        <p><b>一个学习编程的网站</b></p>
    </body>
</html>

文档树中的每个节点都是 Python 对象,这些对象大致分为四类:Tag , NavigableString , BeautifulSoup , Comment 。其中使用最多的是 Tag 和 NavigableString。

  • Tag:标签类,HTML 文档中所有的标签都可以看做 Tag 对象。
  • NavigableString:字符串类,指的是标签中的文本内容,使用 text、string、strings 来获取文本内容。
  • BeautifulSoup:表示一个 HTML 文档的全部内容,您可以把它当作一个人特殊的 Tag 对象。
  • Comment:表示 HTML 文档中的注释内容以及特殊字符串,它是一个特殊的 NavigableString。
Tag节点

标签(Tag)是组成 HTML 文档的基本元素。在 BS4 中,通过标签名和标签属性可以提取出想要的内容。看一组简单的示例:

python 复制代码
from bs4 import BeautifulSoup
soup = BeautifulSoup('<p class="Web site url"><b>www.youbafu.com</b></p>', 'html.parser')
# 获取整个p标签的html代码
print(soup.p)  # 获取p标签
print(soup.p.b)  # 获取b标签
print(soup.p.text)  # 获取p标签内容,使用NavigableString类中的string、text、get_text()
print(soup.p.attrs)  # 返回一个字典,里面是多有属性和值
print(type(soup.p))  # 查看返回的数据类型
print(soup.p['class'])  # 根据属性,获取标签的属性值,返回值为列表
soup.p['class'] = ['Web', 'Site']  # 给class属性赋值,此时属性值由列表转换为字符串
print(soup.p)

输出结果如下:

python 复制代码
soup.p输出结果:
<p class="Web site url"><b>www.bpsend.net</b></p>

soup.p.b输出结果:
<b>www.bpsend.net</b>

soup.p.text输出结果:
www.bpsend.net

soup.p.attrs输出结果:
{'class': ['Web', 'site', 'url']}

type(soup.p)输出结果:
<class 'bs4.element.Tag'>

soup.p['class']输出结果:
['Web', 'site', 'url']

class属性重新赋值:
<p class="Web site url"><b>www.bpsend.net</b></p>
遍历节点

Tag 对象提供了许多遍历 tag 节点的属性,比如 contents、children 用来遍历子节点;parent 与 parents 用来遍历父节点;而 next_sibling 与 previous_sibling 则用来遍历兄弟节点 。示比如下:

html 复制代码
html_doc = """<html><head><title>"跟渣男教父学编程"</title></head><body><p class="title"><b>www.youbafu.com</b></p><p class="website">一个学习编程的网站</p><a href="http://www.bpsend.net/python/" id="link1">python教程</a>
<a href="http://www.bpsend.net/c/" id="link2">c语言教程</a>
</body></html>"""
soup = BeautifulSoup(html_doc, 'html.parser')
body_tag = soup.body
print(body_tag)
print(body_tag.contents)  # 以列表的形式输出,所有子节点

输出结果:

复制代码
<body><p class="title"><b>www.youbafu.com</b></p><p class="website">一个学习编程的网站
</p><a href="http://www.youbafu.com/python/" id="link1">python教程</a>
<a href="http://www.youbafu.com/c/" id="link2">c语言教程</a>
</body>

# 以列表的形式输出
[<p class="title"><b>www.youbafu.com</b></p>, <p class="website">一个学习编程的网站
</p>, <a href="http://www.youbafu.com/python/" id="link1">python教程</a>, '\n', <a href="http://www.youbafu.com/c/" id="link2">c语言教程</a>, ' ']

Tag 的 children 属性会生成一个可迭代对象,可以用来遍历子节点,示比如下:

复制代码
for child in body_tag.children:
    print(child)

输出结果:

复制代码
<p class="title"><b>www.youbafu.com</b></p>
<p class="website">一个学习编程的网站</p>
<a href="http://www.youbafu.com/python/" id="link1">python教程</a>
<a href="http://www.youbafu.com/c/" id="link2">c语言教程</a>
find_all() 与 find()

find_all() 与 find() 是解析 HTML 文档的常用方法,它们可以在 HTML 文档中按照一定的条件(相当于过滤器)查找所需内容。find() 与 find_all() 的语法格式相似,希望大家在学习的时候,可以举一反三。

BS4 库中定义了许多用于搜索的方法,find() 与 find_all() 是最为关键的两个方法,其余方法的参数和使用与其类似。

find_all()

find_all() 方法用来搜索当前 tag 的所有子节点,并判断这些节点是否符合过滤条件,最后以列表形式将符合条件的内容返回,语法格式如下:

复制代码
find_all(name, attrs, recursive, text, limit)

参数说明:

  • name:查找所有名字为 name 的 tag 标签,字符串对象会被自动忽略。
  • attrs:按照属性名和属性值搜索 tag 标签,注意由于 class 是 Python 的关键字,所以要使用 "class_"。
  • recursive:find_all() 会搜索 tag 的所有子孙节点,设置 recursive=False 可以只搜索 tag 的直接子节点。
  • text:用来搜文档中的字符串内容,该参数可以接受字符串 、正则表达式 、列表、True。
  • limit:由于 find_all() 会返回所有的搜索结果,这样会影响执行效率,通过 limit 参数可以限制返回结果的数量。

find_all() 使用示比如下:

html 复制代码
from bs4 import BeautifulSoup
html_doc = """<html><head><title>"跟渣男教父学编程"</title></head><body><p class="title"><b>www.bpsend.net</b></p><p class="website">一个学习编程的网站</p><a href="http://www.bpsend.net/python/" id="link1">python教程</a><a href="http://www.bpsend.net/c/" id="link2">c语言教程</a><a href="http://www.bpsend.net/django/" id="link3">django教程</a><p class="vip">加入我们阅读所有教程</p><a href="http://www.bpsend.net/vip" id="link4">成为vip</a>"""
# 创建soup解析对象
soup = BeautifulSoup(html_doc, 'html.parser')
print(soup.find_all("a"))  # 查找所有a标签并返回
print(soup.find_all("a", limit=2))  # 查找前两条a标签并返回

按照标签属性以及属性值查找 HTML 文档,如下所示:

复制代码
print(soup.find_all("p", class_="website"))
print(soup.find_all(id="link4"))

正则表达式、列表,以及 True 也可以当做过滤条件,使用示比如下:

python 复制代码
import re
# 查找tag标签
print(soup.find_all(['b', 'a']))
# 正则表达式匹配id属性值
print(soup.find_all('a', id=re.compile(r'.\d')))
print(soup.find_all(id=True))  # True可以匹配任何值,下面代码会查找所有tag,并返回相应的tag名称
for tag in soup.find_all(True):
    print(tag.name, end=" ")
# 输出所有以b开始的tag标签

BS4 为了简化代码,为 find_all() 提供了一种简化写法,如下所示:

复制代码
soup.find_all("a")

上述两种的方法的输出结果是相同的。

find()

find() 方法与 find_all() 方法类似,不同之处在于 find() 只返回第一个匹配的元素,而不是列表。语法格式如下:

复制代码
find(name, attrs, recursive, text)

文档总结

一、核心知识点回顾

1. Requests 库到底能做什么?

Requests 就是帮你"向网站要数据"的工具。

打个比方:

  • 你去餐厅点菜,服务员帮你下单 → Requests 帮你向服务器发请求
  • 服务员把菜端给你 → Requests 把网页内容返回给你

核心功能:

复制代码
requests.get()    → 获取网页(最常用)
requests.post()   → 提交数据(登录、搜索等)
response.text     → 拿到文本(HTML、JSON)
response.content  → 拿到二进制(图片、文件)

2. GET vs POST 请求
对比项 GET POST
用途 获取数据 提交数据
参数位置 URL 里(?key=value) 请求体里
参数参数 params={} data={}
例子 搜索、浏览页面 登录、发表评论
长度限制 有(URL长度限制)

使用场景:

  • 浏览网页、搜索商品 → GET
  • 登录账号、提交表单 → POST

3. 响应对象常用属性
复制代码
response = requests.get(url)

response.status_code   # 状态码:200成功、404找不到、403禁止
response.text          # 文本内容(字符串)
response.content       # 二进制内容(下载图片用)
response.url           # 实际请求的URL(可能有跳转)
response.headers       # 响应头信息
response.encoding      # 编码格式
response.cookies       # Cookie信息

状态码速查:

  • 200 ------ 成功
  • 301/302 ------ 重定向(跳转了)
  • 400 ------ 请求参数错误
  • 403 ------ 被拒绝(可能触发反爬)
  • 404 ------ 页面不存在
  • 500 ------ 服务器错误

4. 实用请求参数
参数 作用 示例
headers 伪装浏览器 {'User-Agent': '...'}
params GET 请求参数 {'wd': 'python'}
data POST 请求参数 {'username': 'xxx'}
timeout 超时时间 timeout=10
proxies 代理 IP {'http': 'http://IP:端口'}
verify SSL 认证 verify=False(跳过证书检查)
auth 用户认证 auth=('user', 'pass')

5. BeautifulSoup 基础

BS4 就是帮你"从 HTML 里找数据"的工具。

创建解析对象:

复制代码
from bs4 import BeautifulSoup
soup = BeautifulSoup(html, 'html.parser')  # 或 'lxml'

四大对象:

  • Tag ------ 标签(<a>, <div> 等)
  • NavigableString ------ 标签里的文本
  • BeautifulSoup ------ 整个文档
  • Comment ------ 注释内容

6. BS4 查找元素
方法 作用 返回值
find() 找第一个匹配的 Tag 对象
find_all() 找所有匹配的 列表
select() CSS 选择器 列表

常用查找方式:

python 复制代码
# 按标签名
soup.find('a')
soup.find_all('a')

# 按 class
soup.find('div', class_='item')
soup.find_all('div', class_='item')

# 按 id
soup.find(id='kw')

# 按属性
soup.find('a', href='http://example.com')

# 获取文本
tag.text
tag.get_text()
tag.string

# 获取属性
tag['href']
tag['src']
tag.get('class')
find() vs find_all():

# find() 只返回第一个
result = soup.find('a')
print(result)  # <a href="...">第一个链接</a>

# find_all() 返回所有(列表)
results = soup.find_all('a')
print(results)  # [<a...>, <a...>, <a...>]

# 限制数量
results = soup.find_all('a', limit=3)  # 只返回前3个

7. 下载图片/文件
python 复制代码
import requests

# 下载图片
url = 'https://example.com/image.jpg'
response = requests.get(url)

# 用 content(二进制),不是 text!
with open('image.jpg', 'wb') as f:
    f.write(response.content)

关键点:

  • 下载图片/文件 → 用 response.content
  • 获取网页文本 → 用 response.text
  • 打开文件用 'wb' 模式(二进制写入)

二、常见坑与解决方案

坑1:response.text 乱码

复制代码
症状:打印出来是乱码
原因:编码识别错误(默认 ISO-8859-1)
解决:response.encoding = 'utf-8' 或 response.apparent_encoding

坑2:下载图片打不开

复制代码
症状:下载的图片无法打开
原因:用了 response.text 而不是 response.content
解决:下载二进制文件必须用 .content

坑3:find_all() 返回空列表

复制代码
症状:soup.find_all('div', class_='item') 返回 []
原因1:class 名写错了
原因2:HTML 结构和你想的不一样
解决:先 print(soup) 看看实际 HTML 长什么样

坑4:class 是 Python 关键字

复制代码
症状:soup.find('div', class='item') 报错
原因:class 是 Python 保留字
解决:用 class_(加下划线)

坑5:代理 IP 不可用

复制代码
症状:requests.get() 超时或报错
原因:免费代理经常失效
解决:换代理,或设置 timeout 避免卡死

坑6:忘记加 User-Agent

复制代码
症状:返回 403 或空内容
原因:网站识别出你是爬虫
解决:加 headers={'User-Agent': '...'}

三、学习建议

  1. Requests 优先于 urllib ------ 代码简洁,功能强大
  2. BS4 适合新手 ------ 比正则直观,比 lxml 简单
  3. 先打印 response ------ 看看状态码和内容,再决定怎么处理
  4. 下载文件用 content ------ 别用 text,否则文件会损坏
  5. 加 timeout 保平安 ------ 避免程序永远卡住
  6. 先找单个再找多个 ------ 先用 find() 测试,再用 find_all() 批量
相关推荐
似璟如你2 小时前
Java 开发者的 Go 语法基础:从 0 开始快速上手 Go
java·开发语言·后端·golang·go·编程语言
LccKyI2 小时前
C#学习day05(开发福彩双色球系统附思维导图)
开发语言·学习·c#
zzz_23682 小时前
TencentDB-Agent-Memory 深度解析:让多个 Agent 共享项目经验的记忆中枢
java·开发语言·jvm·人工智能·agent·memory·tencent db
DeepVisionary2 小时前
再观察小星火:当大厂分成“冰封“,国产轻模式创作者平台如何跑出加速度
python·自动化
gb42152872 小时前
python中unstructured库和langchain-unstructured库在解析pdf文件的时候的区别?
python·langchain·pdf
vx-程序开发2 小时前
django医院预约挂号系统---附源码23353
java·javascript·spring boot·python·eclipse·django·php
charlie1145141912 小时前
IMX6ULL WM8960 的移植——前置介绍
开发语言·c++·开源项目·嵌入式linux
雪山青木3 小时前
全国微博签到数据201912-202004
大数据·爬虫·python·数据挖掘·数据分析·新浪微博
迷迭香yy3 小时前
Python实战:涨停板“假封板”识别系统的工程实现
开发语言·人工智能·python
charlie1145141913 小时前
Cinux是如何管理进程的 —— 上下文与调度
开发语言·c++·操作系统·开源项目