当前位置: 首页 > news >正文

100天精通Python(爬虫篇)——第113天:爬虫基础模块之urllib详细教程大全

文章目录
  • 1. urllib概述
  • 2. urllib.request模块
    • 1. urllib.request.urlopen()
    • 2. urllib.request.urlretrieve()
    • 3. urllib.request.Request()
    • 4. urllib.request.install_opener()
    • 5. urllib.request.build_opener()
    • 6. urllib.request.AbstractBasicAuthHandler
    • 7. urllib.request.HTTPBasicAuthHandler
    • 8. urllib.request.HTTPDigestAuthHandler
    • 9. urllib.request.ProxyHandler
    • 10. urllib.request.HTTPSHandler
    • 11. urllib.request.HTTPCookieProcessor
  • 3. urllib.parse模块
    • 1. urllib.parse.urlparse()
    • 2. urllib.parse.urlunparse()
    • 3. urllib.parse.urlsplit()
    • 4. urllib.parse.urlunsplit()
    • 5. urllib.parse.urljoin()
    • 6. urllib.parse.urlencode()
    • 7. urllib.parse.urldecode()
    • 8. urllib.parse.quote()
    • 9. urllib.parse.unquote()
    • 10. urllib.parse.quote_plus()
    • 11. urllib.parse.unquote_plus()
  • 3. urllib.error模块
    • 1. urllib.error.URLError()
    • 2. urllib.error.HTTPError()
    • 3. urllib.error.ContentTooShortError())
  • 4. urllib.robotparser模块
    • 1. urllib.robotparser.RobotFileParser()
  • 5. 实战案例
    • 1. 万能图片下载
    • 2. 爬取豆瓣电影Top250

1. urllib概述

urllib 是 Python 内置的一个标准库(无需安装),专门用于处理与 URL 相关的各种操作,包括网页请求、数据解析等。它提供了较为底层和灵活的接口,允许开发者进行各种类型的网络请求和数据传输。urllib 最初是 Python 2 中的一个模块,在 Python 3 中被拆分成了几个子模块,以便更好地组织功能。

urllib 的主要子模块包括:

  • urllib.request:用于打开和读取 URL。它提供了类似于浏览器请求的功能,可以发送 GET 和 POST 请求,并处理 HTTP 和 HTTPS 协议。该模块还允许设置请求头、处理 Cookies 以及使用自定义的处理器。
  • urllib.parse:用于解析和构建 URL。它提供了一系列函数,用于将 URL 字符串解析成各个组成部分(如协议、主机名、路径、查询参数等),以及将各个组件重新组合成完整的 URL 字符串。
  • urllib.error:用于处理 urllib.request 引发的异常。它定义了一系列异常类,如 URLError(表示底层的 URL 错误)和 HTTPError(表示 HTTP 请求中的错误)。
  • urllib.robotparser:用于解析 robots.txt 文件。robots.txt 文件是网站用来告诉搜索引擎爬虫哪些页面可以抓取,哪些页面不能抓取的。这个模块允许开发者检查一个 URL 是否允许被爬虫访问。

虽然很多人更喜欢使用requests库,但是urllib作为Python爬虫起源库,了解和掌握它还是很有必要的,并且在一些特殊情况下urllib可能会更有优势。

2. urllib.request模块

urllib.request是Python标准库中的核心模块,用于打开和读取url。它提供了一系列函数和类,用于发送HTTP和HTTPS请求,以及处理服务器响应。下面将详细介绍urllib.request模块中的所有函数及其用法。

1. urllib.request.urlopen()

urllib.request.urlopen()是最常用的函数之一,用于打开一个URL并读取其内容。它接受一个URL作为参数,并返回一个类文件对象,该对象可用于读取响应内容。

import urllib.request# 1、输出需要请求网页链接
url = 'http://www.baidu.com'# 2、模拟浏览器向服务器发送请求
response = urllib.request.urlopen(url)# 3、获取响应数据中的页面源码(注意:read() 返回的是字节形式的二进制数据,返回数据会被 b'xxx' 进行包裹)
content = response.read()# 4、打印二进制数据
# print(content)
# 输出结果:b'<!DOCTYPE html><!--STATUS OK--><html> 中间省略。。。。。。</html># 5、将二进制数据转成字符串,这里需要网页对应的编码格式(例如:<meta http-equiv="Content-Type" content="text/html;charset=utf-8">),charset= 的就是编码格式 utf-8
html_str = content.decode('utf-8')# 6、输出字符串
print(html_str)

该函数还可以接受一个可选的data参数,用于发送POST请求。如果提供了data参数,则请求方法将自动设置为POST。

data = b'param1=value1&param2=value2'  # 注意数据必须是字节类型
response = urllib.request.urlopen(url, data=data)

此外,urlopen()还支持超时设置、SSL证书验证等高级功能。

2. urllib.request.urlretrieve()

urllib.request.urlretrieve()函数用于将URL指向的内容下载到本地文件。它接受两个参数:URL和本地文件名。该函数将URL的内容保存到指定的本地文件中,并返回一个包含两个元素的元组:本地文件名和HTTP消息头。

import urllib.requesturl = 'http://www.example.com/image.jpg'
filename = 'image.jpg'
urllib.request.urlretrieve(url, filename)

3. urllib.request.Request()

urllib.request.Request()类用于构造一个HTTP请求对象。通过创建Request对象,可以设置请求的URL、方法(GET、POST等)、头部信息、数据等。然后,可以使用urlopen()函数发送该请求。

import urllib.requesturl = 'http://www.example.com'
headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64)'
}
request = urllib.request.Request(url, headers=headers)
response = urllib.request.urlopen(request)
content = response.read().decode('utf-8')
print(content)

4. urllib.request.install_opener()

urllib.request.install_opener()函数用于全局设置用于打开URLs的opener对象。opener对象是一个实现了BaseHandlerOpenerDirector接口的类实例。通过安装自定义的opener,可以更改URL打开方式,例如添加代理、处理cookies等。

import urllib.request
from urllib.request import HTTPHandler, build_opener# 创建一个HTTPHandler对象
http_handler = HTTPHandler()# 使用HTTPHandler创建一个opener对象
opener = build_opener(http_handler)# 安装opener
urllib.request.install_opener(opener)# 现在,所有的urlopen调用都会使用自定义的opener
response = urllib.request.urlopen('http://www.example.com')

5. urllib.request.build_opener()

urllib.request.build_opener()函数用于构建一个opener对象。该函数接受一个或多个BaseHandler子类的实例作为参数,并返回一个OpenerDirector对象。通过构建自定义的opener,可以灵活地处理各种HTTP请求。

# 示例同上,不再赘述

6. urllib.request.AbstractBasicAuthHandler

urllib.request.AbstractBasicAuthHandler是一个抽象基类,用于处理基本的HTTP认证。它不能直接实例化,但可以作为自定义认证处理器的基类。

7. urllib.request.HTTPBasicAuthHandler

urllib.request.HTTPBasicAuthHandlerAbstractBasicAuthHandler的一个子类,用于处理HTTP基本认证。通过创建该类的实例,并设置用户名和密码,可以自动处理需要基本认证的HTTP请求。

import urllib.request
from urllib.request import HTTPBasicAuthHandler, build_opener# 创建一个HTTPBasicAuthHandler对象,并设置用户名和密码
auth_handler = HTTPBasicAuthHandler()
auth_handler.add_password('realm', 'http://www.example.com', 'username', 'password')# 使用HTTPBasicAuthHandler创建一个opener对象
opener = build_opener(auth_handler)# 安装opener
urllib.request.install_opener(opener)# 现在,所有的urlopen调用都会自动处理基本认证
response = urllib.request.urlopen('http://www.example.com')

8. urllib.request.HTTPDigestAuthHandler

urllib.request.HTTPDigestAuthHandler类用于处理HTTP摘要认证。与HTTPBasicAuthHandler类似,通过创建该类的实例并设置用户名和密码,可以自动处理需要摘要认证的HTTP请求。

9. urllib.request.ProxyHandler

urllib.request.ProxyHandler类用于处理代理服务器。通过创建该类的实例,并设置代理服务器的地址和端口,可以自动处理通过代理服务器发送的HTTP请求。

import urllib.request
from urllib.request import ProxyHandler, build_opener# 创建一个ProxyHandler对象,并设置代理服务器的地址和端口
proxy_handler = ProxyHandler({'http': 'http://proxy.example.com:8080','https': 'http://proxy.example.com:8080'
})# 使用ProxyHandler创建一个opener对象
opener = build_opener(proxy_handler)# 安装opener
urllib.request.install_opener(opener)# 现在,所有的urlopen调用都会通过代理服务器发送请求
response = urllib.request.urlopen('http://www.example.com')

10. urllib.request.HTTPSHandler

urllib.request.HTTPSHandler类用于处理HTTPS请求。通过创建该类的实例,并可能设置SSL上下文,可以处理加密的HTTPS请求。

11. urllib.request.HTTPCookieProcessor

urllib.request.HTTPCookieProcessor类用于处理HTTP cookies。通过创建该类的实例,并传入一个cookiejar.CookieJar对象,可以自动处理HTTP请求和响应中的cookies。

import urllib.request
from urllib.request import HTTPCookieProcessor, build_opener
from http.cookiejar import CookieJar# 创建一个CookieJar对象
cookie_jar = CookieJar()# 创建一个HTTPCookieProcessor对象,并传入CookieJar对象
cookie_processor = HTTPCookieProcessor(cookie_jar)# 使用HTTPCookieProcessor创建一个opener对象
opener = build_opener(cookie_processor)# 安装opener
urllib.request.install_opener(opener)# 现在,所有的urlopen调用都会自动处理cookies
response = urllib.request.urlopen('http://www.example.com')

3. urllib.parse模块

urllib.parse是Python标准库中的一个模块,专门用于URL解析和构建。它提供了一系列函数,用于解析URL的不同部分、编码和解码URL组件、以及构建新的URL。下面将详细介绍urllib.parse模块中的所有函数及其用法。

1. urllib.parse.urlparse()

urlparse()函数用于将URL解析为六个组件:协议、网络位置、路径、参数、查询字符串和片段。

from urllib.parse import urlparseurl = 'http://www.example.com:80/path?query=string#fragment'
parsed_url = urlparse(url)print(parsed_url.scheme)   # 输出协议,如http
print(parsed_url.netloc)   # 输出网络位置,如www.example.com:80
print(parsed_url.path)     # 输出路径,如/path
print(parsed_url.params)   # 输出参数(已废弃,现代URL中不常见)
print(parsed_url.query)    # 输出查询字符串,如query=string
print(parsed_url.fragment) # 输出片段,如fragment

注意:params部分在现代URL中并不常见,因此urlparse()返回的params属性通常为空。

2. urllib.parse.urlunparse()

urlunparse()函数是urlparse()的逆操作,它将六个组件重新组合成一个URL。

from urllib.parse import urlunparsecomponents = ('http', 'www.example.com:80', '/path', '', 'query=string', 'fragment')
url = urlunparse(components)
print(url)  # 输出: http://www.example.com:80/path?query=string#fragment

3. urllib.parse.urlsplit()

urlsplit()函数与urlparse()类似,但它不解析参数部分,而是将参数和查询字符串一起作为查询部分返回。

from urllib.parse import urlspliturl = 'http://www.example.com:80/path;param?query=string#fragment'
split_url = urlsplit(url)print(split_url.scheme)    # 输出协议
print(split_url.netloc)    # 输出网络位置
print(split_url.path)      # 输出路径(包括参数)
print(split_url.query)     # 输出查询字符串
print(split_url.fragment)  # 输出片段

4. urllib.parse.urlunsplit()

urlunsplit()函数是urlsplit()的逆操作,它将五个组件重新组合成一个URL。

from urllib.parse import urlunsplitcomponents = ('http', 'www.example.com:80', '/path;param', 'query=string', 'fragment')
url = urlunsplit(components)
print(url)  # 输出: http://www.example.com:80/path;param?query=string#fragment

5. urllib.parse.urljoin()

urljoin()函数用于将基本URL与相对URL组合成一个绝对URL。

from urllib.parse import urljoinbase_url = 'http://www.example.com/path/'
relative_url = 'subpath/page.html'
absolute_url = urljoin(base_url, relative_url)
print(absolute_url)  # 输出: http://www.example.com/path/subpath/page.html

如果相对URL以/开头,则它会替换基本URL的路径部分;如果以#?开头,则它会替换基本URL的片段或查询部分。

6. urllib.parse.urlencode()

urlencode()函数用于将字典或两个元组的序列编码为查询字符串。

from urllib.parse import urlencodeparams = {'param1': 'value1', 'param2': 'value2'}
query_string = urlencode(params)
print(query_string)  # 输出: param1=value1&param2=value2

也可以传递一个元组的序列来指定键值对:

params = [('param1', 'value1'), ('param2', 'value2')]
query_string = urlencode(params)
print(query_string)  # 输出同上

7. urllib.parse.urldecode()

注意:实际上,urllib.parse模块中并没有直接名为urldecode()的函数,但有一个parse_qs()和一个parse_qsl()函数,它们用于解码查询字符串。

  • parse_qs():将查询字符串解析为一个字典,其中键是参数名,值是参数值的列表(因为查询字符串中可能有多个同名参数)。

    from urllib.parse import parse_qs

    query_string = ‘param1=value1&param2=value2&param2=value3’
    params = parse_qs(query_string)
    print(params) # 输出: {‘param1’: [‘value1’], ‘param2’: [‘value2’, ‘value3’]}

  • parse_qsl():与parse_qs()类似,但返回的是一个元组的序列,每个元组包含一个参数名和对应的参数值。

    from urllib.parse import parse_qsl

    query_string = ‘param1=value1&param2=value2’
    params = parse_qsl(query_string)
    print(params) # 输出: [(‘param1’, ‘value1’), (‘param2’, ‘value2’)]

8. urllib.parse.quote()

quote()函数用于将字符串中的特殊字符转义为URL编码的字符。

from urllib.parse import quotestring = 'Hello World! 你好,世界!'
encoded_string = quote(string)
print(encoded_string)  # 输出: Hello%20World%21%20%E4%BD%A0%E5%A5%BD%EF%BC%8C%E4%B8%96%E7%95%8C%EF%BC%81

9. urllib.parse.unquote()

unquote()函数是quote()的逆操作,它将URL编码的字符转换回原始字符串。

from urllib.parse import unquoteencoded_string = 'Hello%20World%21%20%E4%BD%A0%E5%A5%BD%EF%BC%8C%E4%B8%96%E7%95%8C%EF%BC%81'
decoded_string = unquote(encoded_string)
print(decoded_string)  # 输出: Hello World! 你好,世界!

10. urllib.parse.quote_plus()

quote_plus()函数与quote()类似,但它会将空格编码为加号(+)而不是百分号加20(%20)。

from urllib.parse import quote_plusstring = 'Hello World! 你好,世界!'
encoded_string = quote_plus(string)
print(encoded_string)  # 输出: Hello+World%21+%E4%BD%A0%E5%A5%BD%EF%BC%8C%E4%B8%96%E7%95%8C%EF%BC%81

11. urllib.parse.unquote_plus()

unquote_plus()函数是quote_plus()的逆操作,它将加号(+)转换回空格。

from urllib.parse import unquote_plusencoded_string = 'Hello+World%21+%E4%BD%A0%E5%A5%BD%EF%BC%8C%E4%B8%96%E7%95%8C%EF%BC%81'
decoded_string = unquote_plus(encoded_string)
print(decoded_string)  # 输出: Hello World! 你好,世界!

3. urllib.error模块

urllib.error是Python标准库urllib中的一个模块,专门用于处理在使用urllib进行URL操作时可能遇到的错误。它包含了一系列异常类,这些异常类可以帮助你捕获和处理不同类型的错误情况。本文将详细介绍urllib.error模块中的所有异常类及其用法。

1. urllib.error.URLError()

URLErrorurllib.error模块中所有URL错误的基础类。当你遇到与URL相关的错误时,通常会首先捕获到这个异常。

from urllib.error import URLErrortry:# 尝试打开一个URL(这里只是一个示例,实际代码可能涉及更复杂的操作)with urllib.request.urlopen('http://example.com/nonexistent') as response:# 处理响应pass
except URLError as e:print(f"URLError: {e.reason}")  # 输出错误的具体原因

URLError有一个reason属性,它包含了错误的详细信息。这个属性通常是一个字符串或者是一个异常对象,具体取决于引发错误的底层原因。

2. urllib.error.HTTPError()

HTTPErrorURLError的一个子类,它专门用于处理HTTP协议相关的错误。当你尝试打开一个HTTP URL,并且服务器返回了一个错误状态码(如404表示未找到)时,就会引发这个异常。

from urllib.error import HTTPErrortry:# 尝试打开一个不存在的HTTP URLwith urllib.request.urlopen('http://example.com/nonexistent') as response:# 处理响应(这里不会执行到,因为会引发HTTPError)pass
except HTTPError as e:print(f"HTTPError: {e.code} {e.reason}")  # 输出HTTP状态码和错误原因print(f"Headers: {e.headers}")  # 输出响应头(如果有的话)# 你可以在这里进一步处理错误,比如重试请求或者记录日志

HTTPError有几个重要的属性:

  • code:HTTP状态码(如404, 500等)。
  • reason:错误原因的简短描述(如"Not Found")。
  • headers:包含响应头的HTTPMessage对象(如果有的话)。
  • fp:一个文件对象,包含了服务器返回的错误页面的内容(如果有的话,通常用于调试)。

3. urllib.error.ContentTooShortError())

ContentTooShortErrorurllib.error模块中的一个异常类,它会在下载的内容长度小于预期时引发。这通常意味着连接在内容完全传输之前就被关闭了。

from urllib.error import ContentTooShortErrortry:# 尝试下载一个文件(这里只是一个示例,实际代码可能涉及更复杂的操作)with urllib.request.urlopen('http://example.com/largefile') as response, open('file.dat', 'wb') as f:f.write(response.read())
except ContentTooShortError as e:print(f"ContentTooShortError: The content was shorter than expected.")# 你可以在这里处理错误,比如重试下载或者记录日志

注意说明:

  • 在实际的Python环境中,urllib.requesturllib.error通常是同时使用的。urllib.request模块用于发起URL请求,而urllib.error模块则用于处理这些请求可能引发的错误。
  • urllib.error模块中可能还有其他一些异常类,但URLErrorHTTPError是最常见和最重要的。其他异常类通常是更具体的情况或者更低级别的错误,它们的使用频率相对较低。
  • 在处理URL相关的错误时,最好能够捕获到具体的异常类(如HTTPError),以便能够针对不同类型的错误采取不同的处理措施。如果只需要捕获所有URL相关的错误,可以捕获URLError基类。

4. urllib.robotparser模块

urllib.robotparser模块是Python标准库中的一个重要组成部分,它专门用于解析和遵守网站的robots.txt文件。robots.txt文件是一个文本文件,通常放在网站的根目录下,用于告诉搜索引擎爬虫哪些页面可以抓取,哪些页面不可以抓取。urllib.robotparser模块提供了一个RobotFileParser类,通过这个类,我们可以方便地判断某个URL是否可以被特定的爬虫抓取。

1. urllib.robotparser.RobotFileParser()

RobotFileParser类是urllib.robotparser模块中的核心类,它提供了多个方法来解析robots.txt文件并判断URL的抓取权限。

1. 构造函数

urllib.robotparser.RobotFileParser(url='')
  • url:可选参数,指定robots.txt文件的URL。如果不提供,可以在后续使用set_url()方法设置。

2. set_url(url)

设置robots.txt文件的URL。

  • urlrobots.txt文件的URL。

3. read()

读取并解析robots.txt文件。这个方法不会返回任何内容,但必须对文件进行读取操作,否则后续的can_fetch()方法判断将始终为False

4. parse(lines)

解析robots.txt文件的内容。这个方法的参数lines应该是robots.txt文件中的某些行内容,通常是通过读取文件并拆分得到的。这个方法也可以用于直接解析字符串形式的robots.txt内容。

  • linesrobots.txt文件中的行内容列表。

5. can_fetch(user_agent, url)

判断指定的user_agent是否有权限抓取指定的url

  • user_agent:爬虫的名称或标识符。
  • url:要抓取的URL。
  • 返回值:如果user_agent有权限抓取url,则返回True;否则返回False

6. mtime()

返回上次抓取和分析robots.txt文件的时间。这对于长时间运行的爬虫来说很有用,因为它可以帮助爬虫定期检查并更新robots.txt文件的最新内容。

  • 返回值:上次抓取和分析robots.txt文件的时间(以秒为单位的UNIX时间戳)。

7. modified()

将当前时间设置为上次抓取和分析robots.txt文件的时间。这个方法通常用于在爬虫启动或重置时设置初始时间。

以下是一个使用urllib.robotparser模块判断URL抓取权限的示例:

from urllib.robotparser import RobotFileParser# 创建一个RobotFileParser对象
robots = RobotFileParser()# 设置robots.txt文件的URL
robots.set_url("http://www.example.com/robots.txt")# 读取并解析robots.txt文件
robots.read()# 判断Baiduspider是否有权限抓取http://www.example.com/page1.html
print(robots.can_fetch("Baiduspider", "http://www.example.com/page1.html"))# 判断Googlebot是否有权限抓取http://www.example.com/page2.html
print(robots.can_fetch("Googlebot", "http://www.example.com/page2.html"))

在这个示例中,我们首先创建了一个RobotFileParser对象,并设置了robots.txt文件的URL。然后,我们调用read()方法读取并解析了robots.txt文件。最后,我们使用can_fetch()方法判断了两个不同的爬虫是否有权限抓取两个不同的URL。

注意事项:

  • 在使用urllib.robotparser模块时,请确保你的爬虫遵守robots.txt文件中的规则。尊重网站的抓取限制是爬虫开发中的一项重要道德和法律义务。
  • urllib.robotparser模块仅提供了基本的robots.txt解析和判断功能。如果你需要更复杂的爬虫管理功能(如动态更新robots.txt文件、处理多个网站的抓取规则等),可能需要自行实现或使用第三方库。

5. 实战案例

1. 万能图片下载

使用urllib库编写一个“万能”图片下载代码需要考虑几个关键点:如何获取图片的URL、如何处理不同网站的图片链接格式、以及如何处理网络错误和文件写入。尽管无法编写一个真正意义上能处理所有情况的“万能”代码(因为每个网站的结构和限制都可能不同),但我们可以编写一个相对通用的图片下载器,它能够处理一些常见的场景。

以下是一个简单的Python脚本,它使用urllib库从给定的图片URL下载图片,并将其保存到本地:

import urllib.request
import urllib.parse
import osdef download_image(image_url, save_path='images/', filename=None):"""从给定的图片URL下载图片,并保存到指定的路径。:param image_url: 图片的URL。:param save_path: 保存图片的文件夹路径(默认为'images/')。:param filename: 保存图片的文件名(如果为None,则使用URL中的文件名)。:return: 保存的图片文件名。"""# 确保保存路径存在if not os.path.exists(save_path):os.makedirs(save_path)# 如果未指定文件名,则从URL中提取if filename is None:parsed_url = urllib.parse.urlparse(image_url)filename = os.path.basename(parsed_url.path)# 构建完整的保存路径full_path = os.path.join(save_path, filename)try:# 打开URL并读取图片数据with urllib.request.urlopen(image_url) as response, open(full_path, 'wb') as out_file:# 将图片数据写入文件data = response.read()out_file.write(data)print(f"图片已保存到 {full_path}")except urllib.error.URLError as e:print(f"无法下载图片:{e.reason}")except Exception as e:print(f"发生错误:{e}")return full_path# 示例使用
if __name__ == "__main__":image_url = "https://profile-avatar.csdnimg.cn/53a04a4caf1f4dc098a03b5d8840dbdb_yuan2019035055.jpg"  # 替换为实际的图片URLdownload_image(image_url)

用代码测试下载我的博客头像成功下载:
在这里插入图片描述

2. 爬取豆瓣电影Top250

使用urllib库来爬取豆瓣电影Top 250的列表需要处理多个分页,解析HTML内容,并提取所需的信息。由于豆瓣电影Top 250是分页显示的,每页显示25部电影,因此你需要循环访问每个分页并解析其内容,将使用BeautifulSoup库来解析HTML。

首先,确保你已经安装了BeautifulSouplxml(一个用于解析HTML和XML的库):

pip install beautifulsoup4 lxml

代码说明:

  1. 导入库:除了urllib库外,还导入了BeautifulSoup用于HTML解析。

  2. 设置基础URL和请求头BASE_URL是豆瓣电影Top 250的起始URL,HEADERS包含了一个用户代理字符串,用于模拟浏览器请求,以避免被网站封禁。

  3. 定义爬取函数fetch_top250_movies函数循环访问豆瓣电影Top 250的每个分页,使用urllib.request.Request构建请求对象,并添加请求头。然后,使用urllib.request.urlopen打开URL,读取HTML内容,并通过BeautifulSoup解析内容。

  4. 解析电影信息:在函数内部,使用find_all方法找到所有类名为itemdiv元素,这些元素包含了每部电影的信息。然后,遍历这些元素,提取电影的标题、评分和链接。

  5. 示例使用:在__main__块中调用fetch_top250_movies函数,并打印出每部电影的标题、评分和链接。

完整代码如下(免责声明 :此代码仅用于学习和研究目的,请勿用于商业用途或违反法律的行为,后果自负):

import urllib.request
import urllib.parse
from urllib.error import URLError, HTTPError
from bs4 import BeautifulSoup# 豆瓣电影Top 250基础URL
BASE_URL = "https://movie.douban.com/top250"
HEADERS = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3'}# 定义一个函数来爬取Top 250电影
def fetch_top250_movies(start=0):movies = []for i in range(10):  # 豆瓣Top 250共10页,每页25部url = f"{BASE_URL}?start={start}"try:request = urllib.request.Request(url, headers=HEADERS)response = urllib.request.urlopen(request)html_content = response.read().decode('utf-8')soup = BeautifulSoup(html_content, 'lxml')# 解析每部电影的信息items = soup.find_all('div', class_='item')for item in items:movie = {}title_tag = item.find('span', class_='title')rating_tag = item.find('span', class_='rating_num')link_tag = item.find('a')if title_tag and rating_tag and link_tag:movie['title'] = title_tag.get_text(strip=True)movie['rating'] = rating_tag.get_text(strip=True)movie['link'] = link_tag['href']movies.append(movie)start += 25  # 每页25部电影except (URLError, HTTPError) as e:print(f"Error fetching {url}: {e.reason}")breakreturn movies# 示例使用
if __name__ == "__main__":top250_movies = fetch_top250_movies()for movie in top250_movies:print(f"Title: {movie['title']}, Rating: {movie['rating']}, Link: {movie['link']}")

运行结果展示:
在这里插入图片描述

相关文章:

100天精通Python(爬虫篇)——第113天:爬虫基础模块之urllib详细教程大全

文章目录 1. urllib概述2. urllib.request模块 1. urllib.request.urlopen()2. urllib.request.urlretrieve()3. urllib.request.Request()4. urllib.request.install_opener()5. urllib.request.build_opener()6. urllib.request.AbstractBasicAuthHandler7. urllib.request.…...

FPGA开发,使用Deepseek V3还是R1(2):V3和R1的区别

以下都是Deepseek生成的答案 FPGA开发&#xff0c;使用Deepseek V3还是R1&#xff08;1&#xff09;&#xff1a;应用场景 FPGA开发&#xff0c;使用Deepseek V3还是R1&#xff08;2&#xff09;&#xff1a;V3和R1的区别 FPGA开发&#xff0c;使用Deepseek V3还是R1&#x…...

Leetcode LRU缓存

LRU 缓存算法思想及代码解析 算法思想 LRU&#xff08;Least Recently Used&#xff0c;最近最少使用&#xff09;缓存 需要满足以下要求&#xff1a; 在 O(1) 时间复杂度内完成 get 和 put 操作。当缓存满时&#xff0c;删除最近最少使用的元素&#xff08;即最久没有被访问…...

结合PyMuPDF+pdfplumber,删除PDF指定文本后面的内容

🚀 一、需求场景解析 在日常办公中,我们经常会遇到这样的痛点: 合同处理:收到上百份PDF合同,需要找到"签署页"之后的内容并删除报表加工:批量移除财务报表中的敏感数据区域文档归档:快速提取技术文档的关键章节传统的手动操作方式存在三大致命缺陷: ❗ 耗时…...

【NLP 30、文本匹配任务 —— 传统机器学习算法】

目录 一、文本匹配任务的定义 1.狭义解释 2.广义解释 二、文本匹配的应用 1.问答对话 2.信息检索 3.文本匹配任务应用 三、智能问答 1.智能问答的基本思路 依照基础资源划分&#xff1a; 依照答案产出方式划分 依照NLP相关技术划分 四、智能问答的价值 1.智能客服 2.Faq知识库问…...

修改hosts文件,修改安全属性,建立自己的DNS

初级代码游戏的专栏介绍与文章目录-CSDN博客 我的github&#xff1a;codetoys&#xff0c;所有代码都将会位于ctfc库中。已经放入库中我会指出在库中的位置。 这些代码大部分以Linux为目标但部分代码是纯C的&#xff0c;可以在任何平台上使用。 源码指引&#xff1a;github源…...

springboot + mybatis-plus + druid

目录架构 config MyMetaObjectHandler.java package com.example.config;import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler; import org.apache.ibatis.reflection.MetaObject; import org.springframework.stereotype.Component;import java.util.Date;Com…...

【零基础到精通Java合集】第十一集:List集合框架与泛型

课程标题:List集合框架与泛型(15分钟) 目标:掌握泛型在List中的应用,理解类型安全的重要性,熟练操作泛型集合 0-1分钟:泛型List的意义引入 以“分类储物箱”类比泛型List:明确容器内元素类型(如只能放书籍)。说明泛型的核心作用——编译时类型检查,避免运行时类型…...

计算机网络——子网掩码

一、子网掩码是什么&#xff1f;它长什么样&#xff1f; 子网掩码的定义 子网掩码是一个32位的二进制数字&#xff0c;与IP地址“配对使用”&#xff0c;用于标识IP地址中哪部分属于网络地址&#xff0c;哪部分属于主机地址。 示例&#xff1a;IP地址 192.168.1.10&#xff0c;…...

[自然语言处理]pytorch概述--什么是张量(Tensor)和基本操作

pytorch概述 PyTorch 是⼀个开源的深度学习框架&#xff0c;由 Facebook 的⼈⼯智能研究团队开发和维护&#xff0c;于2017年在GitHub上开源&#xff0c;在学术界和⼯业界都得到了⼴泛应⽤ pytorch能做什么 GPU加速自动求导常用网络层 pytorch基础 量的概念 标量&#xf…...

18.5 ChatGLM2-6B 开源协议深度解读:自由与约束的平衡之道

ChatGLM2-6B 开源协议深度解读:自由与约束的平衡之道 关键词:ChatGLM2 开源协议, 模型授权合规, 商业使用限制, 技术伦理条款, 国产大模型治理 1. 协议核心条款全景解析 ChatGLM2-6B 采用 分层授权模式,其核心条款可归纳为三大维度: #mermaid-svg-xgEnsN0y2TMOR0Hf {font…...

javaweb自用笔记:Vue

Vue 什么是vue vue案例 1、引入vue.js文件 2、定义vue对象 3、定义vue接管的区域el 4、定义数据模型data 5、定义视图div 6、通过标签v-model来绑定数据模型 7、{{message}}直接将数据模型message展示出来 8、由于vue的双向数据绑定&#xff0c;当视图层标签input里的…...

FreeRTOS 源码结构解析与 STM32 HAL 库移植实践(任务创建、删除篇)

1. FreeRTOS源码结构介绍 1.1 下载源码 ​ 点击官网地址&#xff0c;选择 FreeRTOS 202212.01非 LTS 版本&#xff08;非长期支持版&#xff09;&#xff0c;因为这个版本有着最全的历程和更多型号处理器支持。 1.2 文件夹结构介绍 ​ 下载后主文件 FreeRTOSv202212.01 下包…...

第五节:基于Winform框架的串口助手小项目---串口收发《C#编程》

“路漫漫其修远兮&#xff0c;吾将上下而求索” &#xff0c; -----------------------WHAPPY 目标任务&#xff1a; 1 从本地设备列表获取串口。 RegistryKey keyCom Registry.LocalMachine.OpenSubKey("Hardware\DeviceMap\SerialComm"); RegistryKey 是.NET 框…...

CSS2.1基础学习

1.定位盒模型相关 2.浮动 3.使用定位实现三列布局(不可取&#xff0c;定位父级为初始包含块) 4.使用浮动实现三列布局(不可取的原因是中间主列无法优先加载) 5.圣杯布局 6.等高布局 7.双飞翼布局 8.解决IE6下fixed失效问题 9.短暂总结 10.粘连布局 11.BFC是什么 12.BFC实现两列…...

alpine linux 系统最新版安装及使用教程

1.下载镜像包 官网地址 官网下载阿里云镜像站下载华为云镜像站下载清华大学镜像站下载中科大镜像站下载 官方安装文档 2.新建虚拟机 3.编辑虚拟机并开机 4.虚拟机安装 开启虚拟机 首次启动使用root登录&#xff0c;没有密码 登录成功&#xff0c;执行 setup-alpine 命令进…...

【Hudi-SQL DDL创建表语法】

CREATE TABLE 命令功能 CREATE TABLE命令通过指定带有表属性的字段列表来创建Hudi Table。 命令格式 CREATE TABLE [ IF NOT EXISTS] [database_name.]table_name[ (columnTypeList)]USING hudi[ COMMENT table_comment ][ LOCATION location_path ][ OPTIONS (options_lis…...

[Web 安全] PHP 反序列化漏洞 —— POP 链构造思路

关注这个专栏的其他相关笔记&#xff1a;[Web 安全] 反序列化漏洞 - 学习笔记-CSDN博客 0x01&#xff1a;什么是 POP 链&#xff1f; POP 链&#xff08;Payload On Purpose Chain&#xff09;是一种利用 PHP 中的魔法方法进行多次跳转以获取敏感数据的技术。它通常出现在 CTF…...

GPU/CUDA 发展编年史:从 3D 渲染到 AI 大模型时代

目录 文章目录 目录1960s~1999&#xff1a;GPU 的诞生&#xff1a;光栅化&#xff08;Rasterization&#xff09;3D 渲染算法的硬件化实现之路学术界算法研究历程工业界产品研发历程光栅化技术原理光栅化技术的软件实现&#xff1a;OpenGL 3D 渲染管线设计1. 顶点处理&#xff…...

除了DeepSpeed,在训练和推理的时候,显存不足还有什么优化方法吗?FlashAttention 具体是怎么做的

除了DeepSpeed&#xff0c;训练和推理时显存不足的优化方法及FlashAttention原理详解 DeepSpeed的基础内容&#xff1a;ZeRO分布式训练策略 一、显存不足的优化方法 1. 混合精度训练&#xff08;Mixed Precision Training&#xff09; 原理 使用FP16和FP32混合精度&#xff…...

GCC RISCV 后端 -- GCC 后端框架的一些理解

GCC 已经提供了一整套的编译框架&#xff0c;从前端&#xff08;Frontend / GENERIC-Tree&#xff09;对编程语言的语法语义处理&#xff0c;到中端&#xff08;Middle-End / GIMPLE-Tree&#xff09;的目标机器无关&#xff08;Target Indepndent&#xff09;的优化处理&#…...

庖丁解java(一篇文章学java)

(大家不用收藏这篇文章,因为这篇文章会经常更新,也就是删除后重发) 一篇文章学java,这是我滴一个执念... 当然,真一篇文章就写完java基础,java架构,java业务实现,java业务扩展,根本不可能.所以,这篇文章,就是一个索引,索什么呢? 请看下文... 关于决定开始写博文的介绍 …...

Spring框架自带的定时任务:Spring Task详解

文章目录 一、基本使用1、配置&#xff1a;EnableScheduling2、触发器&#xff1a;Scheduled 二、拓展1、修改默认的线程池2、springboot配置 三、源码分析参考资料 一、基本使用 1、配置&#xff1a;EnableScheduling import org.springframework.context.annotation.Config…...

DeepSeek 助力 Vue3 开发:打造丝滑的弹性布局(Flexbox)

前言&#xff1a;哈喽&#xff0c;大家好&#xff0c;今天给大家分享一篇文章&#xff01;并提供具体代码帮助大家深入理解&#xff0c;彻底掌握&#xff01;创作不易&#xff0c;如果能帮助到大家或者给大家一些灵感和启发&#xff0c;欢迎收藏关注哦 &#x1f495; 目录 Deep…...

jwt 存在的无状态的安全问题与解决方案

背景我的需求 解决方法方案1:黑名单存在的问题解决方案问题成本估算: 方案2: 双token刷新核心解决的问题存在的问题 方案3: token与session结合成本估算 方案4: 长连接(websocket) 背景 jwt是无状态的,除了自动失效之外无法手动过期 举个例子: 当我们的token泄露或者密码泄露…...

【Python爬虫】爬取公共交通路网数据

程序来自于Github&#xff0c;以下这篇博客作为完整的学习记录&#xff0c;也callback上一篇爬取公共交通站点的博文。 Bardbo/get_bus_lines_and_stations_data_from_gaode: 这个项目是基于高德开放平台和公交网获取公交线路及站点数据&#xff0c;并生成shp文件&#xff0c;…...

Deepseek API+Python测试用例一键生成与导出-V1

在实际使用场景中&#xff0c;可能只需要获取需求文档中的部分内容&#xff0c;例如特定标题的正文部分、特定段落的表格内容&#xff0c;或者指定图片中的内容。为了满足这一需求&#xff0c;可以对文档清理工具进行优化&#xff0c;支持按标题提取内容、按章节提取表格和图片…...

如何为JAR设置定时重启?

AI越来越火了&#xff0c;我们想要不被淘汰就得主动拥抱。推荐一个人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;最重要的屌图甚多&#xff0c;忍不住分享一下给大家。点击跳转到网站 前面我们说过了如何将jar交由Systemctl管理&#xff0c;下面我们…...

麒麟V10-SP2-x86_64架构系统下通过KVM创建虚拟机及配置虚机的NAT、Bridge两种网络模式全过程

文章目录 一、什么是虚拟化&#xff1f;虚拟化具有哪些优势 二、常见的虚拟化技术1、kvm介绍2、kvm工作原理3、kvm功能 三、安装kvm并启动第一个kvm机器1、环境准备2、安装kvm工具3、启动并设置开机自启 libvirtd 服务4、验证 KVM 模块是否加载5、上传系统镜像到指定目录6、网络…...

三方库总结

一、Glide 目标&#xff1a;熟练掌握各种使用方法&#xff0c;了解其设计&#xff0c;背后原理 如果我设计一个图片显示框架&#xff0c;我会怎么做&#xff1f; 1.加载图片资源-从网络上下载图片资源、从本地加载图片资源 如果是从网络上加载图片&#xff0c;需要用到相关的网…...

用DeepSeek-R1-Distill-data-110k蒸馏中文数据集 微调Qwen2.5-7B-Instruct!

下载模型与数据 模型下载&#xff1a; huggingface&#xff1a; Qwen/Qwen2.5-7B-Instruct HF MirrorWe’re on a journey to advance and democratize artificial intelligence through open source and open science.https://hf-mirror.com/Qwen/Qwen2.5-7B-Instruct 魔搭&a…...

知识图谱的推荐实现方案(Vue)

使用 Vue 实现知识图谱思维导图展示的完整方案&#xff0c;结合主流库和最佳实践&#xff1a; 一、技术选型 组件库特点适用场景MindElixir国产开源、中文文档完善、支持关系线教育类知识图谱GoJS功能强大、商业许可、适合复杂交互企业级应用&#xff08;需付费&#xff09;D3…...

Nessus安装

Nessus&#xff1a;https://pan.quark.cn/s/f5fb09b6d4fb 1.软件安装 点击安装&#xff0c;剩下的下一步即可。 直接下一步安装即可 2.Web端安装 会弹出一个web窗口 开始初始化 创建用户 开始初始化 3.Cracker 会弹一个黑窗口 运行完&#xff0c;回车即可。访问https://loc…...

【大模型基础_毛玉仁】0.概述

更多内容&#xff1a;XiaoJ的知识星球 【大模型基础_毛玉仁】 系列文章参考 系列文章 【大模型基础_毛玉仁】0.概述 【大模型基础_毛玉仁】1.1 基于统计方法的语言模型 更新中。。。。。。 参考 书籍&#xff1a;大模型基础_完整版.pdf Github&#xff1a;https://github.co…...

quillEditor 禁用复制粘贴图片,以及class转style等问题

<template><div><div class"search-term"><el-form :inline"true" :model"searchInfo" class"demo-form-inline"><el-form-item label"案例标题"><el-input v-model"searchInfo.titl…...

C语⾔数据类型和变量

C 语言的数据类型 类型分类&#xff1a; C 语言提供丰富的数据类型&#xff0c;包括字符型&#xff08;char、signed char、unsigned char&#xff09;、整型&#xff08;short、int、long 等多种&#xff0c;且各有 signed 和 unsigned 修饰形式&#xff09; 、浮点型&#x…...

centOS 环境 安装redis方法

一、准备centOS环境 参考文章&#xff1a;Hyper-V 安装CentOS7_代码草率了的博客-CSDN博客 二、redis官网 地址&#xff1a;Download | Redis 演示版本为?redis-5.0.14.tar.gz 三、redis源码编译 登录后创建soft目录 进入目录使用wget下载所需资源包 命令&#xff1a;w…...

【Mac】2025-MacOS系统下常用的开发环境配置

早期版本的一个环境搭建参考 1、brew Mac自带终端运行&#xff1a; /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" Installation successful!成功后运行三行命令后更新环境&#xff08;xxx是mac的username&a…...

深入理解动态绑定与多态

动态绑定介绍 Java中的动态绑定&#xff0c;是一种在程序运行时确定方法执行版本的过程。它与多态紧密联系。 在Java中&#xff0c;动态绑定通常发生在以下情况&#xff1a; 方法覆盖&#xff1a;当子类重写父类的一个方法时&#xff0c;调用该方法的行为会根据对象的实际类…...

【数据结构】二叉树总结篇

遍历 递归 递归三部曲&#xff1a; 1.参数和返回值 2.终止条件 3.单层逻辑&#xff08;遍历顺序&#xff09; var preorderTraversal function(root) { // 第一种let res[];const dfsfunction(root){if(rootnull)return ;//先序遍历所以从父节点开始res.push(root.val);//递归…...

Zookeeper 及 基于ZooKeeper实现的分布式锁

1 ZooKeeper 1.1 ZooKeeper 介绍 ZooKeeper是一个开源的分布式协调服务&#xff0c;它的设计目标是将那些复杂且容易出错的分布式一致性服务封装起来&#xff0c;构成一个高效可靠的原语集&#xff0c;并以一系列简单易用的接口提供给用户使用。 原语&#xff1a;操作系统或…...

内嵌踢脚线怎么做能省钱?

家里装修内嵌踢脚线应该怎么做&#xff1f;哪种做法更经济&#xff1f; 先回答内嵌踢脚线应该怎么做&#xff1f; 做内嵌踢脚线有两种办法&#xff0c;简单点来说就是前凸和后挖。 前凸是踢脚线安到原来墙面上&#xff0c;踢脚线是从墙面上凸出来的&#xff0c;想要实现内嵌的效…...

DeepSeek集成到VScode工具,让编程更高效

DeepSeek与VScode的强强联合&#xff0c;为编程效率树立了新标杆。 DeepSeek&#xff0c;一款卓越的代码搜索引擎&#xff0c;以其精准的索引和高速的检索能力&#xff0c;助力开发者在浩瀚的代码海洋中迅速定位关键信息。 集成至VScode后&#xff0c;开发者无需离开熟悉的编辑…...

大模型应用:多轮对话(prompt工程)

概述 在与大型语言模型&#xff08;如ChatGPT&#xff09;交互的过程中&#xff0c;我们常常体验到与智能助手进行连贯多轮对话的便利性。那么&#xff0c;当我们开启一个新的聊天时&#xff0c;系统是如何管理聊天上下文的呢&#xff1f; 一、初始上下文的建立 1. 创建新会…...

洛谷 P1601 A+B Problem(高精)详解c++

我们之前做题碰到的数据范围一般是10^9&#xff0c;多点会达到10^18级别&#xff0c;处理10^9用int就可以存下&#xff0c;10^18次方要用到long long&#xff0c;接着解决加减乘除的问题&#xff0c;但是当数据范围达到了10^10^6的时候&#xff0c;当数据的值特别⼤&#xff0c…...

【云原生】Spring Cloud是什么?Spring Cloud版本介绍

什么是SpringCloud 上一章节介绍了总体的SpringCloud的总体学习章节&#xff0c;因为最近项目刚好需要用到SpringCloud来搭建微服务项目、所以就跟着大家一起来再学习巩固下SpringCloud的相关知识 SpringCloud是基于SpringBoot提供了一套微服务解决方案&#xff0c;包括服务注…...

最节省成本的架构方案:无服务器架构

无服务器架构&#xff08;Serverless Architecture&#xff09;是一种颠覆性的云计算执行模型&#xff0c;它允许开发者专注于编写和部署代码&#xff0c;而无需担心底层服务器基础设施的管理。这种架构以其按需付费、自动伸缩和简化部署等优势&#xff0c;在成本优化方面表现出…...

C++入门续集:

1. 缺省参数&#xff1a; 我们看我们的上图&#xff0c;我们可以看我们的函数Func&#xff0c;我们可以看到我们的函数里面的参数写的是int a 0&#xff1b;这个写法是我们没有见过的&#xff0c;我们之前在C语言里面只见到过说是函数里面会设置参数&#xff0c;但是参数是没有…...

线代[9]|线性代数主要内容及其发展简史(任广千《线性代数的几何意义》的附录1)

文章目录 向量行列式矩阵线性方程组二次型 向量 向量又称为矢量&#xff0c;最初应用与物理学。很多物理量如力、速度、位移以及电场强度、磁感应强度等等都是向量。大约公元前350年前&#xff0c;古希腊著名学者亚里士多德就知道了力可以表示成向量&#xff0c;两个力的组合作…...

C++ Primer 动态内存与智能指针

欢迎阅读我的 【CPrimer】专栏 专栏简介&#xff1a;本专栏主要面向C初学者&#xff0c;解释C的一些基本概念和基础语言特性&#xff0c;涉及C标准库的用法&#xff0c;面向对象特性&#xff0c;泛型特性高级用法。通过使用标准库中定义的抽象设施&#xff0c;使你更加适应高级…...