python爬虫实战——抖音

目录

1、分析主页作品列表标签结构

2、进入作品页前 判断作品是视频作品还是图文作品

3、进入视频作品页面,获取视频

4、进入图文作品页面,获取图片

5、完整参考代码

6、获取全部作品的一种方法


        本文主要使用 selenium.webdriver(Firefox)、BeautifulSoup等相关库,在 centos 系统中,以无登录状态 进行网页爬取练习。仅做学习和交流使用。

安装和配置 driver 参考:

[1]: Linux无图形界面环境使用Python+Selenium最佳实践 - 知乎

[2]: 错误'chromedriver' executable needs to be in PATH如何解 - 知乎

1、分析主页作品列表标签结构

# webdriver 初始化
driver = webdriver.Firefox(options=firefox_options)

# 设置页面加载的超时时间为6秒
driver.set_page_load_timeout(6)

# 访问目标博主页面
# 如 https://www.douyin.com/user/MS4wLjABAAAAnq8nmb35fUqerHx54jlTx76AEkfq-sMD3cj7QdgsOiM
driver.get(target)

# 分别等待 class='e6wsjNLL' 和 class='niBfRBgX' 的元素加载完毕再继续执行
#(等ul.e6wsjNLL加载完就行了)
# WebDriverWait(driver, 6) 设置最长的等待事间为 6 秒
WebDriverWait(driver, 6).until(EC.presence_of_element_located((By.CLASS_NAME, 'e6wsjNLL')))
WebDriverWait(driver, 6).until(EC.presence_of_element_located((By.CLASS_NAME, 'niBfRBgX')))

# 在浏览器中执行脚本,滚动页面到最底部,有可能会显示更多的作品
driver.execute_script('document.querySelector(".wcHSRAj6").scrollIntoView()')
sleep(1)
        
# 使用 beautifulsoup 解析页面源代码
html = BeautifulSoup(driver.page_source, 'lxml')

# 关闭driver
driver.quit()

# 获取作品列表
ul = html.find(class_='e6wsjNLL')

# 获取每一个作品
lis = ul.findAll(class_='niBfRBgX')

2、进入作品页前 判断作品是视频作品还是图文作品

element_a = li.find('a')
# a 标签下如果能找到 class = 'TQTCdYql' 的元素,
# 则表示该作品是图文,如果没有(则为None),则表示该作品是视频
is_pictures = element_a.find(class_='TQTCdYql')


if (not is_pictures) or (not is_pictures.svg):
    # 视频作品
    pass
else:
    # 图文作品
    pass

3、进入视频作品页面,获取视频

# 拼接作品地址
href = f'https://www.douyin.com{element_a["href"]}'
                
# 使用 webdriver 访问作品页面
temp_driver = webdriver.Firefox(options=firefox_options)
temp_driver.set_page_load_timeout(6)
temp_driver.get(href)
    
# 等待 class='D8UdT9V8' 的元素显示后再执行(该元素的内容是作品的发布日期)
WebDriverWait(temp_driver, 6).until(EC.presence_of_element_located((By.CLASS_NAME, 'D8UdT9V8')))
                
html_v = BeautifulSoup(temp_driver.page_source, 'lxml')
temp_driver.quit()
                
# 获取该作品的发布时间
publish_time = html_v.find(class_='D8UdT9V8').string[5:]

video = html_v.find(class_='xg-video-container').video
source = video.find('source')

# 为该作品创建文件夹(一个作品一个文件夹)
# 以该作品的 发布时间 加 作品类型来命名文件夹
path = create_dir(f'{publish_time}_video')

# 下载作品
download_works(path, f'{get_current_time()}.mp4', f'https:{source["src"]}')

4、进入图文作品页面,获取图片

# 拼接作品页地址
href = f'https:{element_a["href"]}'
                
# 使用webdriver访问作品页面
temp_driver = webdriver.Firefox(options=firefox_options)
temp_driver.set_page_load_timeout(6)
temp_driver.get(href)

# 等待包含作品发表时间的标签加载完成
WebDriverWait(temp_driver, 6).until(EC.presence_of_element_located((By.CLASS_NAME, 'YWeXsAGK')))

# 获取当前页面的源代码,关闭webdriver,交给beautifulsoup来处理
# (剩下的任务 继续使用webdriver也能完成)
html_p = BeautifulSoup(temp_driver.page_source, 'lxml')
temp_driver.quit()
                
# 获取该作品的发布时间
publish_time = f'{html_p.find(class_="YWeXsAGK")}'[-23:-7]
                
# 图片列表
img_ul = html_p.find(class_='KiGtXxLr')
imgs = img_ul.findAll('img')
                
# 为该作品创建文件夹,以作品的发布时间+作品类型+图片数量(如果是图片类型作品)
path = create_dir(f'{publish_time}_pictures_{len(imgs)}')

# 遍历图片,获取url 然后下载
for img in imgs:
    download_works(path, f'{get_current_time()}.webp', f'{img["src"]}')

5、完整参考代码

# -*- coding: utf-8 -*-

import threading,requests,os,zipfile
from selenium.webdriver.common.by import By
from selenium.common.exceptions import NoSuchElementException
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.wait import WebDriverWait
from datetime import datetime
from selenium import webdriver
from selenium.webdriver.firefox.options import Options
from pyvirtualdisplay import Display
from time import sleep
from bs4 import BeautifulSoup
from selenium.common.exceptions import WebDriverException

display = Display(visible=0, size=(1980, 1440))
display.start()

firefox_options = Options()
firefox_options.headless = True
firefox_options.binary_location = '/home/lighthouse/firefox/firefox'

# 获取当前时间
def get_current_time():
    now = datetime.now()
    format_time = now.strftime("_%Y-%m-%d__%H-%M-%S-%f__")
    return format_time

# 设置一个根路径,作品文件以及日志文件都保留在此
ABS_PATH = f'/home/resources/{get_current_time()}'

# 创建目录,dir_name 是作品的发布时间,格式为:2024-02-26 16:59,需要进行处理
def create_dir(dir_name):
    dir_name = dir_name.replace(' ', '-').replace(':', '-')
    path = f'{ABS_PATH}/{dir_name}'
    try:
        os.makedirs(path)
    except FileExistsError:
        print(f'试图创建已存在的文件, 失败({path})')
    else:
        print(f'创建目录成功  {path}')
    finally:
        return path

# 下载    目录名称,当前文件的命名,下载的地址
def download_works(dir_name, work_name, src):
    response = requests.get(src, stream=True)
    if response.status_code == 200:
        with open(f'{dir_name}/{work_name}', mode='wb') as f:
            for chunk in response.iter_content(1024):
                f.write(chunk)

# 判断作品是否已经下载过
def test_work_exist(dir_name):
    dir_name = dir_name.replace(' ', '-').replace(':', '-')
    path = f'{ABS_PATH}/{dir_name}'
    if os.path.exists(path) and os.path.isdir(path):
        if os.listdir(path):
            return True
    return False

def get_all_works(target):
    try:
        driver = webdriver.Firefox(options=firefox_options)
        driver.set_page_load_timeout(6)
        # 目标博主页面
        driver.get(target)
        WebDriverWait(driver, 6).until(EC.presence_of_element_located((By.CLASS_NAME, 'e6wsjNLL')))
        WebDriverWait(driver, 6).until(EC.presence_of_element_located((By.CLASS_NAME, 'niBfRBgX')))
        
        driver.execute_script('document.querySelector(".wcHSRAj6").scrollIntoView()')
        sleep(1)
        
        html = BeautifulSoup(driver.page_source, 'lxml')
        driver.quit()
        # 作品列表
        ul = html.find(class_='e6wsjNLL')
        # 每一个作品
        lis = ul.findAll(class_='niBfRBgX')
        
        for li in lis:
            element_a = li.find('a')
            is_pictures = element_a.find(class_='TQTCdYql')
            
            if (not is_pictures) or (not is_pictures.svg):
                href = f'https://www.douyin.com{element_a["href"]}'
                
                temp_driver = webdriver.Firefox(options=firefox_options)
                temp_driver.set_page_load_timeout(6)
                temp_driver.get(href)
    
                WebDriverWait(temp_driver, 6).until(EC.presence_of_element_located((By.CLASS_NAME, 'D8UdT9V8')))
                
                # 不是必须,剩余内容webdriver也能胜任
                html_v = BeautifulSoup(temp_driver.page_source, 'lxml')
                temp_driver.quit()
                
                # 获取该作品的发布时间
                publish_time = html_v.find(class_='D8UdT9V8').string[5:]

                # if test_work_exist(f'{publish_time}_video'):
                #     continue
                
                video = html_v.find(class_='xg-video-container').video
                source = video.find('source')
                
                # 为该作品创建文件夹
                path = create_dir(f'{publish_time}_video')
                
                # 下载作品
                download_works(path, f'{get_current_time()}.mp4', f'https:{source["src"]}')
            else:
                href = f'https:{element_a["href"]}'
                
                temp_driver = webdriver.Firefox(options=firefox_options)
                temp_driver.set_page_load_timeout(6)
                temp_driver.get(href)
                WebDriverWait(temp_driver, 6).until(EC.presence_of_element_located((By.CLASS_NAME, 'YWeXsAGK')))

                # 使用 beautifulsoup 不是必须
                html_p = BeautifulSoup(temp_driver.page_source, 'lxml')
                temp_driver.quit()
                
                publish_time = f'{html_p.find(class_="YWeXsAGK")}'[-23:-7]
                
                # 图片列表
                img_ul = html_p.find(class_='KiGtXxLr')
                imgs = img_ul.findAll('img')

                # if test_work_exist(f'{publish_time}_pictures_{len(imgs)}'):
                #     continue
                
                path = create_dir(f'{publish_time}_pictures_{len(imgs)}')
                for img in imgs:
                    download_works(path, f'{get_current_time()}.webp', f'{img["src"]}')
                
        display.stop()
        print('##### finish #####')
    except WebDriverException as e: 
        print(f"捕获到 WebDriverException: {e}")  
    except Exception as err:
        print("捕获到其他错误 get_all_works 末尾")
        print(err)
    finally:
        driver.quit()
        display.stop()

# 将目录进行压缩
def zipdir(path, ziph):
    # ziph 是 zipfile.ZipFile 对象
    for root, dirs, files in os.walk(path):
        for file in files:
            ziph.write(os.path.join(root, file),
                       os.path.relpath(os.path.join(root, file), os.path.join(path, '..')))

def dy_download_all(target_url):
    get_all_works(target_url)

    directory_to_zip = ABS_PATH  # 目录路径
    output_filename = f'{ABS_PATH}.zip'  # 输出ZIP文件的名称

    with zipfile.ZipFile(output_filename, 'w', zipfile.ZIP_DEFLATED) as zipf:
        zipdir(directory_to_zip, zipf)

    return f'{ABS_PATH}.zip'             # 返回下载地址

if __name__ == '__main__':
    # 简单测试
    url = input('请输入博主主页url:')
    path = dy_download_all(url)
    print('下载完成')
    print(f'地址:{path}')


测试结果:

6、获取全部作品的一种方法

        上述的操作是在无登录状态下进行的,即使在webdriver中操作让页面滚动,也只能获取到有限的作品,大约是 20 项左右。对此提出一个解决方案。

         以登录状态(或者有cookies本地存储等状态)访问目标博主页面,滚动到作品最底部,然后在控制台中执行JavaScript脚本,获取全部作品的信息(在这里是作品链接以及作品类型),然后写出到文本文件中。

JavaScript 代码: 

let ul = document.querySelector('.e6wsjNLL');

// 存放结果
works_list = [];

// 遍历,每一次都加入一个对象,包括作品页的地址、作品是否为图片作品
ul.childNodes.forEach((e)=>{
  let href = e.querySelector('a').href;
  let is_pictures = e.querySelector('a').querySelector('.TQTCdYql') ? true : false;
  works_list.push({href, is_pictures})
})

// 创建一个Blob对象,包含要写入文件的内容  
var content = JSON.stringify(works_list);  
var blob = new Blob([content], {type: "text/plain;charset=utf-8"});  
  
// 创建一个链接元素  
var link = document.createElement("a");  
  
// 设置链接的href属性为Blob对象的URL  
link.href = URL.createObjectURL(blob);  
  
// 设置链接的下载属性,指定下载文件的名称  
link.download = "example.txt";  
  
// 触发链接的点击事件,开始下载文件  
link.click();

写出结果: 

        列表中的每一个元素都是一个对象,href 是作品的地址,is_pictures 以 boolean 值表示该作品是否为图片作品

        

然后在 python 中读入该文件,使用 json 解析,转成字典列表的形式,遍历列表,对每一个字典(就是每一个作品)进行处理即可。

示例代码:

         win 环境下

import json
import threading,requests,os
from bs4 import BeautifulSoup
from seleniumwire import webdriver
from selenium.webdriver.common.by import By
from selenium.common.exceptions import NoSuchElementException
from datetime import datetime
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.wait import WebDriverWait

# 获取当前时间
def get_current_time():
    now = datetime.now()
    format_time = now.strftime("_%Y-%m-%d__%H-%M-%S-%f__")
    return format_time

# 设置一个根路径,作品文件以及日志文件都保留在此
ABS_PATH = f'F:\\{get_current_time()}'

# 创建目录,dir_name 是作品的发布时间,格式为:2024-02-26 16:59,需要进行处理
def create_dir(dir_name):
    dir_name = dir_name.replace(' ', '-').replace(':', '-')
    path = f'{ABS_PATH}/{dir_name}'
    try:
        os.makedirs(path)
    except FileExistsError:
        print(f'试图创建已存在的文件, 失败({path})')
    else:
        print(f'创建目录成功  {path}')
    finally:
        return path

# 下载    目录名称,当前文件的命名,下载的地址
def download_works(dir_name, work_name, src):
    response = requests.get(src, stream=True)
    if response.status_code == 200:
        with open(f'{dir_name}/{work_name}', mode='wb') as f:
            for chunk in response.iter_content(1024):
                f.write(chunk)

# 判断作品是否已经下载过
def test_work_exist(dir_name):
    dir_name = dir_name.replace(' ', '-').replace(':', '-')
    path = f'{ABS_PATH}/{dir_name}'
    if os.path.exists(path) and os.path.isdir(path):
        if os.listdir(path):
            return True
    return False

# 下载一个作品
def thread_task(ul):
    for item in ul:
        href = item['href']
        is_pictures = item['is_pictures']

        if is_pictures:
            temp_driver = webdriver.Chrome()
            temp_driver.set_page_load_timeout(6)
            temp_driver.get(href)
            WebDriverWait(temp_driver, 6).until(EC.presence_of_element_located((By.CLASS_NAME, 'YWeXsAGK')))

            # 使用 beautifulsoup 不是必须
            html_p = BeautifulSoup(temp_driver.page_source, 'lxml')
            temp_driver.quit()

            publish_time = f'{html_p.find(class_="YWeXsAGK")}'[-23:-7]

            # 图片列表
            img_ul = html_p.find(class_='KiGtXxLr')
            imgs = img_ul.findAll('img')

            # if test_work_exist(f'{publish_time}_pictures_{len(imgs)}'):
            #     continue

            path = create_dir(f'{publish_time}_pictures_{len(imgs)}')
            for img in imgs:
                download_works(path, f'{get_current_time()}.webp', f'{img["src"]}')
        else:
            temp_driver = webdriver.Chrome()
            temp_driver.set_page_load_timeout(6)
            temp_driver.get(href)

            WebDriverWait(temp_driver, 6).until(EC.presence_of_element_located((By.CLASS_NAME, 'D8UdT9V8')))

            # 不是必须,剩余内容webdriver也能胜任
            html_v = BeautifulSoup(temp_driver.page_source, 'lxml')
            temp_driver.quit()

            # 获取该作品的发布时间
            publish_time = html_v.find(class_='D8UdT9V8').string[5:]

            # if test_work_exist(f'{publish_time}_video'):
            #     continue

            video = html_v.find(class_='xg-video-container').video
            source = video.find('source')

            # 为该作品创建文件夹
            path = create_dir(f'{publish_time}_video')

            # 下载作品
            download_works(path, f'{get_current_time()}.mp4', f'https:{source["src"]}')

if __name__ == '__main__':
    content = ''
    # 外部读入作品链接文件
    with open('../abc.txt', mode='r', encoding='utf-8') as f:
        content = json.load(f)

    length = len(content)
    if length <= 3 :
        thread_task(content)
    else:
        # 分三个线程
        ul = [content[0: int(length / 3) + 1], content[int(length / 3) + 1: int(length / 3) * 2 + 1],
                   content[int(length / 3) * 2 + 1: length]]
        for child_ul in ul:
            thread = threading.Thread(target=thread_task, args=(child_ul,))
            thread.start()


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

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

相关文章

【WSN覆盖优化】基于改进黏菌算法的无线传感器网络覆盖 WSN覆盖优化【Matlab代码#65】

文章目录 【可更换其他算法&#xff0c;获取资源请见文章第5节&#xff1a;资源获取】1. 改进SMA算法1.1 改进参数p1.2 混沌精英突变策略 2. WSN节点感知模型3. 部分代码展示4. 仿真结果展示5. 资源获取 【可更换其他算法&#xff0c;获取资源请见文章第5节&#xff1a;资源获取…

Python 基于 OpenCV 视觉图像处理实战 之 开发环境搭建

Python 基于 OpenCV 视觉图像处理实战 之 开发环境搭建 目录 Python 基于 OpenCV 视觉图像处理实战 之 开发环境搭建 一、简单介绍 二、该项目案例的开发环境 三、Python 环境搭建 1、Python 安装包下载 2、这里以 下载 Python 3.10.9 为例 3、安装 Python 3.10.9 4、检…

http协议-基于TCP的超文本传输协议

一、通过http最终实现一个效果 用我们自己电脑上的浏览器去访问我们自己写的python程序&#xff0c;这个程序就可以满足浏览器的需求&#xff0c;你可以从浏览器里面看到自己写出来的网页。所谓的协议就是一种规定。 二、http协议 正常情况下www.xxx是域名&#xff0c;将来…

前端实现复制粘贴功能

在前端开发的世界里&#xff0c;复制粘贴功能就像是那个总是被忽视&#xff0c;却在关键时刻能救你一命的老朋友。我们习惯了用那些古老的魔法咒语&#xff08;document.execCommand(copy)&#xff09;来实现这一功能&#xff0c;但时代在进步&#xff0c;技术在更新&#xff0…

LNMP架构之web服务器实战

LNMP架构 1.nginx部署 systemctl disable --now keepalived.service 关闭keepalived服务&#xff0c;避免冲突 将下载好的nginx软件压缩包直接拖入mobaxterm目录即可 tar zxf nginx-1.23.3.tar.gz cd nginx-1.23.3/ yum install -y gcc pcre-devel openssl-devel #安装依…

LInux系统架构----Nginx模块rewrite的规则与应用场景

LInux系统架构----Nginx模块rewrite的规则与应用场景 一.rewrite跳转实现 Nginx实现跳转通过ngx_http_rewrite_module模块支持URL重写、支持if条件判断&#xff0c;但是不支持else跳转时&#xff0c;循环最多可以执行10次&#xff0c;超过后nginx将返回500错误注&#xff1a;…

0基础使用dockerfile构建容器镜像

目录 一、使用dockerfile构建镜像 1.1、dockerfile指令 1.FROM 2.RUN 3.CMD 4.ENTRYPOINT 5.EXPOSR ​编辑 6.ADD和COPY ​编辑7.volume 8.USER 二、案例1&#xff1a;dockerfile构建httpd镜像 构建一个指定挂载点的httpd镜像 三、案例2&#xff1a;构建tomcat镜…

使用endnote插入引用文献导致word英文和数字变成符号的解决方案

使用endnote插入引用文献导致word英文和数字变成符号的解决方案 如图使用endnote插入引用文献导致word英文和数字变成符号字体Wingdings Wingdings 是一个符号字体系列&#xff0c;它将许多字母渲染成各式各样的符号&#xff0c;用途十分广泛。 **解决方法&#xff1a;**直接通…

【相关问题解答1】bert中文文本摘要代码:import时无法找到包时,几个潜在的原因和解决方法

【相关问题解答1】bert中文文本摘要代码 写在最前面问题1问题描述一些建议import时无法找到包时&#xff0c;几个潜在的原因和解决方法1. 模块或包的命名冲突解决方法&#xff1a; 2. 错误的导入路径解决方法&#xff1a; 3. 第三方库的使用错误解决方法&#xff1a; 4. 包未正…

gpt-4-all模型中转实现

最近才完成这个功能&#xff0c;相信知道这个模型的人&#xff0c;应该已经熟悉了。这是我的中转&#xff1a;openai-api Chatbox配置如下&#xff1a; 模型测试&#xff1a; 1&#xff09;图片生成 2&#xff09;文件分析&#xff0c;链接读取&#xff1a;

WPF实时时间显示demo(MVVM)

跟着b站的视频学习做一个界面,它里面的时间不能实时刷新,因此自己研究写一个,同时加深一下自己对MVVM的理解. 运行结果: 实现步骤: 1.界面 界面设计就是放置了一个TextBlock,它的text绑定了ViewModel层里面的公告属性CurrentTime. <Grid><TextBlock Text"{Bindi…

【Vite+Ts】自动按需引入Element-Plus

安装插件 cnpm i -D unplugin-vue-components unplugin-auto-import unplugin-element-plus修改vite.config.ts // vite.config.ts import AutoImport from "unplugin-auto-import/vite"; import Components from "unplugin-vue-components/vite"; impor…

白嫖AWS云服务器,验证、注册指南

背景 不知道你想不想拥有一台属于自己的云服务器呢&#xff0c;拥有一台自己的云服务器可以建站&#xff0c;可以在上面搭建个人博客&#xff0c;今天我就来教大家如何申请亚马逊 AWS 免费云服务器&#xff0c;这个云服务器可以长达12个月的免费。而且到期后可以继续换个账号继…

【Flink SQL】Flink SQL 基础概念:SQL 动态表 连续查询

Flink SQL 基础概念&#xff1a;SQL 动态表 & 连续查询 1.SQL 应用于流处理的思路2.流批处理的异同点及将 SQL 应用于流处理核心解决的问题3.SQL 流处理的输入&#xff1a;输入流映射为 SQL 动态输入表4.SQL 流处理的计算&#xff1a;实时处理底层技术 - SQL 连续查询5.SQL…

Arduino IDE的下载和安装

一、Arduino的介绍 Arduino是一款开源电子原型平台&#xff0c;主要包含两部分&#xff1a;硬件&#xff08;各种型号的Arduino板&#xff09;和软件&#xff08;Arduino IDE&#xff09;。这个平台由意大利的Massimo Banzi、David Cuartielles等人共同开发设计&#xff0c;并于…

OPPO后端二面,凉了!

这篇文章的问题来源于一个读者之前分享的 OPPO 后端凉经&#xff0c;我对比较典型的一些问题进行了分类并给出了详细的参考答案。希望能对正在参加面试的朋友们能够有点帮助&#xff01; Java String 为什么是不可变的? public final class String implements java.io.Seri…

【毕设级项目】基于嵌入式的智能家居控制板(完整工程资料源码)

基于嵌入式的智能家居控制板演示效果 基于嵌入式的智能家居控制板 前言&#xff1a; 随着科技的不断进步&#xff0c;物联网技术得到了突飞猛进的发展。智能家居是物联网技术的典型应用领域之一。智能家居系统将独立家用电器、安防设备连接成一个具有思想的整体&#xff0c;实现…

清华把大模型用于城市规划,回龙观和大红门地区成研究对象

引言&#xff1a;参与式城市规划的新篇章 随着城市化的不断推进&#xff0c;传统的城市规划方法面临着越来越多的挑战。这些方法往往需要大量的时间和人力&#xff0c;且严重依赖于经验丰富的城市规划师。为了应对这些挑战&#xff0c;参与式城市规划应运而生&#xff0c;它强…

汽车IVI中控开发入门及进阶(十四):功能安全

前言: 是时候需要来说一下功能安全了,有没有发现现在很多主机厂、Tier1对芯片等BOM物料有些是有功能安全需求的,那么什么是功能安全呢? 车辆中电子元件数量的增加增加了更多故障的可能性,对驾驶员和乘客的风险更高。这种风险的增加导致汽车行业将功能安全标准作为汽车设计…

C库函数-getopt函数总结学习

1、简介 getopt函数是命令行参数解析函数 1、1命令行组成 Command name 程序文件名 operands 操作对象 option 选项 option argument 选项参数 getopt()函数将传递给mian()函数的argc,argv作为参数&#xff0c;同时接受字符串参数optstring – optstring是由选项Option字母组…
最新文章