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.request

url = '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.request

url = '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 urlparse

url = '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 urlunparse

components = ('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 urlsplit

url = '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 urlunsplit

components = ('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 urljoin

base_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 urlencode

params = {'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 quote

string = '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 unquote

encoded_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_plus

string = '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_plus

encoded_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 URLError

try:
    # 尝试打开一个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 HTTPError

try:
    # 尝试打开一个不存在的HTTP URL
    with 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 ContentTooShortError

try:
    # 尝试下载一个文件(这里只是一个示例,实际代码可能涉及更复杂的操作)
    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 os

def 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"  # 替换为实际的图片URL
    download_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}")
            break
    return 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']}")

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/967138.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

win32汇编环境,结构体的使用示例一

;运行效果 ;win32汇编环境,结构体的使用示例一 ;举例说明结构体的定义&#xff0c;如何访问其中的成员&#xff0c;使用assume指令指向某个结构体&#xff0c;利用偏移得到成员值等 ;直接抄进RadAsm可编译运行。重要部分加备注。 ;下面为asm文件 ;>>>>>>>…

opencv:基于暗通道先验(DCP)的内窥镜图像去雾

目录 项目大体情况 暗通道先验&#xff08;Dark Channel Prior, DCP&#xff09;原理 项目代码解析 该项目是由我和我导师与舟山某医院合作开发的一个基于暗通道先验&#xff08;Dark Channel Prior&#xff0c;DCP&#xff09;的内窥镜图像去雾方法。具体来说&#xff0c;…

Java 大视界 -- Java 大数据在智能政务中的应用与服务创新(78)

&#x1f496;亲爱的朋友们&#xff0c;热烈欢迎来到 青云交的博客&#xff01;能与诸位在此相逢&#xff0c;我倍感荣幸。在这飞速更迭的时代&#xff0c;我们都渴望一方心灵净土&#xff0c;而 我的博客 正是这样温暖的所在。这里为你呈上趣味与实用兼具的知识&#xff0c;也…

【DeepSeek】DeepSeek概述 | 本地部署deepseek

目录 1 -> 概述 1.1 -> 技术特点 1.2 -> 模型发布 1.3 -> 应用领域 1.4 -> 优势与影响 2 -> 本地部署 2.1 -> 安装ollama 2.2 -> 部署deepseek-r1模型 1 -> 概述 DeepSeek是由中国的深度求索公司开发的一系列人工智能模型&#xff0c;以其…

数据库,数据表的增删改查操作

一.数据库的基本操作 &#xff08;1&#xff09;创建数据库 创建数据库就是在数据库系统中划分一块存储数据的空间&#xff0c;方便数据的分配、放置和管理。在MySQL中使用CREATE DATABASE命令创建数据库&#xff0c;语法格式如下: CREATE DATABASE数据库名称; 注&#xff1a…

书籍《新能源汽车动力电池安全管理算法设计》和《动力电池管理系统核心算法》脑图笔记

目录 一、阅读背景二、《新能源汽车动力电池安全管理算法设计》脑图笔记三、《动力电池管理系统核心算法》脑图笔记四、后记参考学习 一、阅读背景 如今身处新能源动力电池行业&#xff0c;欲对动力电池相关算法做一些了解&#xff0c;通过查找相关电子书app&#xff0c;最后找…

激活函数篇 03 —— ReLU、LeakyReLU、RandomizedLeakkyReLU、PReLU、ELU

本篇文章收录于专栏【机器学习】 以下是激活函数系列的相关的所有内容: 一文搞懂激活函数在神经网络中的关键作用 逻辑回归&#xff1a;Sigmoid函数在分类问题中的应用 整流线性单位函数&#xff08;Rectified Linear Unit, ReLU&#xff09;&#xff0c;又称修正线性单元&a…

Python Pandas(3):DataFrame

1 介绍 DataFrame 是 Pandas 中的另一个核心数据结构&#xff0c;类似于一个二维的表格或数据库中的数据表。它含有一组有序的列&#xff0c;每列可以是不同的值类型&#xff08;数值、字符串、布尔型值&#xff09;。DataFrame 既有行索引也有列索引&#xff0c;它可以被看做由…

【C++高并发服务器WebServer】-14:Select详解及实现

本文目录 一、BIO模型二、非阻塞NIO忙轮询三、IO多路复用四、Select()多路复用实现 明确一下IO多路复用的概念&#xff1a;IO多路复用能够使得程序同时监听多个文件描述符&#xff08;文件描述符fd对应的是内核读写缓冲区&#xff09;&#xff0c;能够提升程序的性能。 Linux下…

算法兵法全略(译文)

目录 始计篇 谋攻篇 军形篇 兵势篇 虚实篇 军争篇 九变篇 行军篇 地形篇 九地篇 火攻篇 用间篇 始计篇 算法&#xff0c;在当今时代&#xff0c;犹如国家关键的战略武器&#xff0c;也是处理各类事务的核心枢纽。算法的世界神秘且变化万千&#xff0c;不够贤能聪慧…

瑞芯微 Rockchip 系列 RK3588 主流深度学习框架模型转成 rknn 模型教程

前言 在瑞芯微 Rockchip 芯片上进行 NPU 推理&#xff0c;需要先将模型文件转换成 rknn 模型文件&#xff0c;才能执行各种推理任务。本文将介绍如何安装各种工具&#xff0c;并最终实现将各种深度学习框架的模型文件转换成 rknn 文件。 本教程不仅适合 RK3588 平台&#xff…

STM32的HAL库开发---高级定时器---互补输出带死区实验

一、互补输出简介 互补输出&#xff1a;OCx输出高电平&#xff0c;则互补通道OCxN输出低电平。OCx输出低电平&#xff0c;则互补通道OCxN输出高电平。 带死区控制的互补输出&#xff1a;OCx输出高电平时&#xff0c;则互补通道OCxN过一会再输出输出低电平。这个时间里输出的电…

git提交到GitHub问题汇总

1.main->master git默认主分支是maser&#xff0c;如果是按照这个分支名push&#xff0c;GitHub会出现两个branch&#xff0c;与预期不符 解决方案&#xff1a;更改原始主分支名为main git config --global init.defaultBranch main2.git&#xff1a;OpenSSL SSL_read: SS…

【图片合并转换PDF】如何将每个文件夹下的图片转化成PDF并合并成一个文件?下面基于C++的方式教你实现

医院在为患者进行诊断和治疗过程中&#xff0c;会产生大量的医学影像图片&#xff0c;如 X 光片、CT 扫描图、MRI 图像等。这些图片通常会按照检查时间或者检查项目存放在不同的文件夹中。为了方便医生查阅和患者病历的长期保存&#xff0c;需要将每个患者文件夹下的图片合并成…

vite + axios 代理不起作用 404 无效

vite axios 代理不起作用 先看官方示例 export default defineConfig({server: {proxy: {// 字符串简写写法/foo: http://localhost:4567,// 选项写法/api: {target: http://jsonplaceholder.typicode.com,changeOrigin: true,rewrite: (path) > path.replace(/^\/api/, )…

Spring Boot接入Deep Seek的API

1&#xff0c;首先进入deepseek的官网&#xff1a;DeepSeek | 深度求索&#xff0c;单击右上角的API开放平台。 2&#xff0c;单击API keys&#xff0c;创建一个API&#xff0c;创建完成务必复制&#xff01;&#xff01;不然关掉之后会看不看api key&#xff01;&#xff01;&…

Windows 系统下使用 Ollama 离线部署 DeepSeek - R1 模型指南

引言 随着人工智能技术的飞速发展&#xff0c;各类大语言模型层出不穷。DeepSeek - R1 凭借其出色的语言理解和生成能力&#xff0c;受到了广泛关注。而 Ollama 作为一款便捷的模型管理和部署工具&#xff0c;能够帮助我们轻松地在本地环境中部署和使用模型。本文将详细介绍如…

Python+Flask搭建属于自己的B站,管理自己电脑里面的视频文件。支持对文件分类、重命名、删除等操作。

适用场景 个人用户:管理本地图片和视频文件,快速查找和分类。 团队协作:共享文件分类标签,提升团队文件管理效率。 教育机构:用于教学资源管理,方便教师和学生查找资料。 企业应用:作为内部文件管理系统,支持批量操作和分类管理。 功能介绍 文件浏览与播放:用户可以浏…

深入Linux系列之进程地址空间

深入Linux系列之进程地址空间 1.引入 那么在之前的学习中&#xff0c;我们知道我们创建一个子进程的话&#xff0c;我们可以在代码层面调用fork函数来创建我们的子进程&#xff0c;那么fork函数的返回值根据我们当前所处进程的上下文是返回不同的值&#xff0c;它在父进程中返…

前端 CSS 动态设置样式::class、:style 等技巧详解

一、:class 动态绑定类名 v-bind:class&#xff08;缩写为 :class&#xff09;可以动态地绑定一个或多个 CSS 类名。 1. 对象语法 通过对象语法&#xff0c;可以根据条件动态切换类名。 <template><div :class"{ greenText: isActive, red-text: hasError }&…