<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:atom="http://www.w3.org/2005/Atom"
>
<channel>
<title><![CDATA[我的EM]]></title> 
<atom:link href="https://top.zhongtongzttb.com.cn/rss.php" rel="self" type="application/rss+xml" />
<description><![CDATA[我的EM]]></description>
<link>https://top.zhongtongzttb.com.cn/</link>
<language>zh-cn</language>
<generator>emlog</generator>

<item>
    <title>AI能代替人工吗？</title>
    <link>https://top.zhongtongzttb.com.cn/?post=86</link>
    <description><![CDATA[<div>AI<strong>无法完全替代人工</strong>，但会<strong>深度替代和重构人工的工作内容</strong>&mdash;&mdash; 其核心是替代人类的<strong>机械性、重复性、规则化劳动</strong>，却难以复刻人类独有的<strong>创造性、情感性、决策性和人文性能力</strong>。最终的职场形态，会是<strong>人机协同</strong>：AI 做 &ldquo;执行者&rdquo;，人类做 &ldquo;决策者、创造者和价值定义者&rdquo;，而非简单的 &ldquo;AI 取代人&rdquo;。</div>
<div>&nbsp;</div>
<div>这个结论的核心，源于 AI 的<strong>技术本质局限</strong>和<strong>人类工作的核心价值属性</strong>的根本差异，具体可以从「能替代的部分」「不能替代的部分」「替代的边界」三个维度说清：</div>
<div>&nbsp;</div>
<h3>一、AI<strong>能高效替代</strong>的人工工作：规则化、无主观判断的劳动</h3>
<div>&nbsp;</div>
<div>这是 AI 当前最核心的价值，也是替代最彻底的领域，覆盖各行各业的基础工作环节，核心特征是<strong>有明确规则、无情感需求、结果可标准化</strong>，AI 做的比人类更快、更准、成本更低，且能 7&times;24 小时工作。</div>
<div>&nbsp;</div>
<ol>
<li><strong>机械重复的执行类工作</strong>：如数据录入、发票核验、客服标准化咨询、电商基础美工抠图、程序员基础代码编写、行政报表统计、银行柜台基础操作等；</li>
<li><strong>海量数据的处理类工作</strong>：如用户行为初步分析、市场数据统计、医疗影像初筛、金融风险初步评估等，AI 能快速处理人类无法在短时间内消化的海量数据，输出基础结论；</li>
<li><strong>固定流程的自动化工作</strong>：如制造业的流水线机械操作、物流的路径规划与分拣、办公场景的自动化脚本执行等，AI 能无缝对接流程，减少人工干预。</li>
</ol>
<div>&nbsp;</div>
<div>这类工作的替代，本质是<strong>生产力的升级</strong>，就像工业革命的蒸汽机替代人力搬运一样，是技术发展的必然，也会释放出更多人力到高价值工作中。</div>
<div>&nbsp;</div>
<h3>二、AI<strong>几乎无法替代</strong>的人工工作：依赖人类独有的核心能力</h3>
<div>&nbsp;</div>
<div>当前的 AI（大模型、机器学习等）均为<strong>数据驱动的 &ldquo;统计学习模型&rdquo;</strong>，它能 &ldquo;模仿&rdquo; 人类的行为，却无法拥有人类的<strong>意识、情感、主观思考和价值判断</strong>，而这正是很多工作的核心价值所在。这类工作，AI 只能做<strong>辅助工具</strong>，永远无法完全替代人类，核心分为四类：</div>
<div>&nbsp;</div>
<ol>
<li><strong>强创造性的工作</strong>：如文学创作、艺术设计、影视编剧、原创音乐、产品创新等。AI 能生成文案、海报、旋律的初稿，但无法创造出有<strong>深度情感、独特思想、人文温度</strong>的作品 &mdash;&mdash; 比如 AI 能写一篇写景散文，却无法复刻作家对生活的独特感悟；能生成一幅画作，却无法传递艺术家的精神表达。</li>
<li><strong>高决策性的战略工作</strong>：如企业高层管理、行业战略制定、投资核心决策、政策制定等。这类工作需要结合<strong>行业经验、人性洞察、突发情况应对、价值判断</strong>，而 AI 的分析仅基于历史数据，无法预判未知的市场变化、无法结合组织的文化和人性特点做出最优决策，只能提供数据支撑，最终的拍板必须由人类完成。</li>
<li><strong>强情感与社交的工作</strong>：如教师、医生、心理咨询师、律师、高端服务顾问、销售核心岗等。这类工作的核心是<strong>人与人之间的情感连接、共情能力和个性化沟通</strong>&mdash;&mdash; 比如医生不仅要诊断病情，还要安抚患者的情绪；教师不仅要传授知识，还要引导学生的价值观；心理咨询师的核心是共情，这些都是 AI 无法模拟的 &ldquo;人类专属能力&rdquo;。</li>
<li><strong>需要临场应变的非标工作</strong>：如应急救援、设备维修现场处理、线下商务谈判等。这类工作没有固定规则，需要根据<strong>现场情况快速反应、灵活变通</strong>，而 AI 的行为被训练数据和算法限定，无法应对超出训练范围的突发场景。</li>
</ol>
<div>&nbsp;</div>
<h3>三、AI 替代人工的<strong>核心边界</strong>：永远是 &ldquo;工具&rdquo;，而非 &ldquo;主体&rdquo;</h3>
<div>&nbsp;</div>
<div>很多人对 AI 替代的焦虑，本质是混淆了 **&ldquo;工具的能力&rdquo; 和 &ldquo;人的主体地位&rdquo;**，而 AI 的技术本质，决定了其替代的边界永远无法突破 &ldquo;工具属性&rdquo;：</div>
<div>&nbsp;</div>
<ol>
<li><strong>AI 无 &ldquo;自主意识&rdquo;</strong>：它不会主动思考、不会产生需求、不会做出无数据支撑的判断，所有输出都是基于训练数据的<strong>概率性结果</strong>，而非 &ldquo;主观选择&rdquo;。比如 AI 能写代码，但不会主动思考 &ldquo;这个功能的业务价值是什么&rdquo;；能做数据分析，但不会判断 &ldquo;这个结论是否符合企业的核心诉求&rdquo;。</li>
<li><strong>AI 的能力源于人类</strong>：AI 的训练数据来自人类的知识和行为，算法由人类设计，输出的结果需要人类<strong>审核、优化、落地</strong>&mdash;&mdash; 比如 AI 生成的营销方案，需要人类结合品牌调性调整；AI 发现的代码 bug，需要人类分析根因并修复；AI 的所有能力，都是人类能力的 &ldquo;延伸&rdquo;，而非 &ldquo;超越&rdquo;。</li>
<li><strong>AI 无法定义 &ldquo;价值&rdquo;</strong>：工作的核心价值，最终由人类的需求和认知决定 &mdash;&mdash; 比如一件艺术品的价值，不在于技法的完美，而在于人类赋予的精神内涵；一个产品的价值，不在于功能的齐全，而在于满足人类的真实需求。AI 无法定义这种 &ldquo;价值&rdquo;，只能围绕人类定义的价值做执行。</li>
</ol>
<div>&nbsp;</div>
<h3>四、最终的职场形态：<strong>人机协同</strong>，而非 &ldquo;非此即彼&rdquo;</h3>
<div>&nbsp;</div>
<div>AI 对人工的影响，从来不是 &ldquo;替代或被替代&rdquo; 的二元选择，而是<strong>重构工作分工</strong>：</div>
<div>&nbsp;</div>
<ul>
<li>AI 承接<strong>低价值、高重复、标准化</strong>的工作环节，让人类从机械执行中解放；</li>
<li>人类聚焦<strong>高价值、创造性、决策性</strong>的工作核心，负责<strong>定义需求、审核结果、制定战略、创造价值</strong>。</li>
</ul>
<div>&nbsp;</div>
<div>比如：程序员用 AI 写基础代码，自己聚焦架构设计和业务逻辑；设计师用 AI 生成初稿，自己做创意优化和情感表达；运营用 AI 做数据统计，自己做策略制定和用户沟通；管理者用 AI 做数据分析，自己做战略决策和团队管理。</div>]]></description>
    <pubDate>Sat, 28 Feb 2026 17:25:45 +0800</pubDate>
    <dc:creator>neal</dc:creator>
    <guid>https://top.zhongtongzttb.com.cn/?post=86</guid>
</item>
<item>
    <title>浅谈AI对现实工作的影响</title>
    <link>https://top.zhongtongzttb.com.cn/?post=85</link>
    <description><![CDATA[<h1>浅谈 AI 对现实工作的影响</h1>
<div>&nbsp;</div>
<div>AI 技术的快速落地与普及，正以<strong>效率重构、分工重塑、能力升级</strong>为核心，渗透到各行各业的现实工作中，其影响并非简单的 &ldquo;替代人力&rdquo;，而是对工作模式、岗位价值、能力要求的全方位重构 &mdash;&mdash; 既大幅释放了重复劳动的效率，也推动着工作内容向高价值、创造性、决策性环节迁移，同时带来了岗位调整与能力适配的新挑战。整体而言，AI 对现实工作的影响是<strong>机遇与挑战并存、替代与升级共生</strong>的，且因行业属性、岗位类型的不同呈现出显著差异。</div>
<div>&nbsp;</div>
<h2>一、核心积极影响：效率提升与工作价值回归</h2>
<div>&nbsp;</div>
<div>AI 的核心作用是成为<strong>人类工作的 &ldquo;效率放大器&rdquo; 和 &ldquo;重复性劳动替代者&rdquo;</strong>，将人从低价值、高耗时、机械性的工作中解放出来，聚焦于更符合人类核心能力的环节，这是其对现实工作最直观、最普遍的正向影响。</div>
<div>&nbsp;</div>
<ol>
<li><strong>替代机械重复劳动，降低时间与人力成本</strong>
<div>&nbsp;</div>
对于包含大量规则化、重复性、标准化操作的工作，AI 能实现全流程或半流程自动化，且在准确性、效率上远超人工。比如行政岗的报表统计、合同初审，财务岗的发票核验、凭证录入，客服岗的标准化咨询回复，程序员的基础代码编写、bug 初筛，设计岗的素材抠图、版式初稿生成等。这类工作无需复杂的主观判断，AI 能以 &ldquo;7&times;24 小时&rdquo; 的模式完成，既减少了人工失误，也让企业降低了基础人力的投入，让员工从 &ldquo;机械执行&rdquo; 中抽身。</li>
<li><strong>提升复杂工作的决策效率与准确性</strong>
<div>&nbsp;</div>
AI 具备强大的数据分析、趋势预测和多维度整合能力，能为高难度的工作决策提供科学支撑，弥补人类在数据处理规模、速度上的短板。比如企业运营的用户行为分析、市场趋势预判，金融行业的风险评估、投资策略建议，医疗行业的影像初诊、病例数据分析，制造业的设备故障预警、生产流程优化等。人类不再需要花费大量时间整理、分析数据，而是基于 AI 的分析结果进行<strong>二次判断和战略决策</strong>，让决策更高效、更贴合实际。</li>
<li><strong>推动跨领域能力融合，降低工作门槛</strong>
<div>&nbsp;</div>
AI 工具的平民化，让非专业人士也能快速掌握原本需要专业技能的工作能力，实现 &ldquo;低门槛完成专业操作&rdquo;。比如不懂编程的运营人员，可通过 AI 生成简单的自动化脚本实现工作提效；不会设计的文案人员，能借助 AI 设计工具生成符合需求的海报、短视频；不精通外语的外贸从业者，可通过 AI 实时翻译完成跨语言沟通。这种能力融合，打破了传统岗位的技能壁垒，让员工能更灵活地应对工作中的多元需求。</li>
<li><strong>优化工作协作模式，提升团队协同效率</strong>
<div>&nbsp;</div>
智能办公工具（如 AI 会议纪要、AI 任务拆解、AI 文档协作）正在重构团队协作的流程：比如会议中 AI 可实时记录要点、生成待办事项并分配责任人，避免人工记录的遗漏；跨部门协作中，AI 可整合各部门的工作数据、进度信息，实现可视化追踪；远程工作中，AI 能实现工作内容的智能同步与反馈。这些工具让协作中的 &ldquo;沟通成本、信息壁垒&rdquo; 大幅降低，让团队协作更高效、更顺畅。</li>
</ol>
<div>&nbsp;</div>
<h2>二、现实挑战：岗位调整与能力适配的双重压力</h2>
<div>&nbsp;</div>
<div>AI 对工作的影响并非全是正向，其自动化和替代属性，也给职场人、企业和行业带来了现实挑战，核心集中在<strong>岗位结构调整、能力要求升级、职业安全感缺失</strong>三个方面，且这种挑战在不同岗位、不同行业中的表现程度截然不同。</div>
<div>&nbsp;</div>
<ol>
<li><strong>基础岗位面临替代与精简，岗位结构重新洗牌</strong>
<div>&nbsp;</div>
那些高度依赖机械重复、标准化操作的<strong>基础型岗位</strong>，是 AI 替代的主要对象，这类岗位的需求会大幅缩减，甚至部分岗位会逐步消失。比如传统的电话客服、数据录入员、银行柜台基础操作员、电商基础美工、简单的文案撰稿人等。与之相对的是，<strong>AI 相关的新增岗位</strong>（如 AI 训练师、AIprompt 工程师、AI 工具运维师）和<strong>复合型岗位</strong>（如懂 AI 的运营、会用 AI 的程序员、结合 AI 的设计师）需求快速增长，行业的岗位结构从 &ldquo;基础人力密集型&rdquo; 向 &ldquo;技术复合型、决策型&rdquo; 转型，部分职场人面临 &ldquo;岗位淘汰&rdquo; 的风险。</li>
<li><strong>职场人能力要求升级，&ldquo;AI 适配能力&rdquo; 成核心竞争力</strong>
<div>&nbsp;</div>
AI 时代，职场人的核心能力不再是 &ldquo;熟练掌握某一项基础技能&rdquo;，而是 **&ldquo;与 AI 协作的能力&rdquo;**&mdash;&mdash; 即能精准向 AI 提需求（写 prompt）、能审核 AI 的输出结果、能将 AI 工具与自身工作结合实现效率提升、能基于 AI 的成果进行创造性优化。对于传统职场人而言，若无法快速掌握 AI 工具的使用方法，无法将自身能力与 AI 结合，就会逐渐失去竞争力。比如同样的文案岗，会用 AI 生成初稿并进行优化的人，效率远高于纯手工撰写的人；同样的程序员，能借助 AI 完成基础编码并聚焦架构设计的人，更受企业青睐。这种能力要求的升级，给职场人带来了持续学习的压力。</li>
<li><strong>部分行业出现 &ldquo;过度依赖 AI&rdquo; 的问题，影响工作质量</strong>
<div>&nbsp;</div>
部分职场人因追求效率，过度依赖 AI 的输出结果，放弃了自身的主观判断和专业思考，导致工作内容出现 &ldquo;同质化、低质量、脱离实际&rdquo; 的问题。比如文案创作中，直接照搬 AI 生成的内容，缺乏个性化和品牌调性；设计工作中，完全使用 AI 生成的素材，导致作品缺乏创意和情感；决策工作中，盲目相信 AI 的分析结果，忽略了实际业务的特殊性和人文因素。这种 &ldquo;AI 依赖症&rdquo;，不仅会降低工作质量，还会让职场人逐渐丧失自身的核心思考能力。</li>
<li><strong>职业安全感缺失，职场焦虑加剧</strong>
<div>&nbsp;</div>
面对 AI 的替代风险，很多职场人尤其是基础岗位的从业者，会产生强烈的<strong>职业安全感缺失</strong>，进而引发职场焦虑。这种焦虑不仅来自 &ldquo;岗位被替代&rdquo; 的担忧，还来自 &ldquo;持续学习的压力&rdquo;&mdash;&mdash; 面对不断更新的 AI 工具和技术，职场人需要持续投入时间和精力学习，否则就会被行业淘汰。这种焦虑在中老年职场人中表现得更为明显，部分人因学习能力下降，难以适应 AI 时代的工作要求，陷入 &ldquo;想转型却无方向&rdquo; 的困境。</li>
</ol>
<div>&nbsp;</div>
<h2>三、差异化影响：行业与岗位的 &ldquo;冰火两重天&rdquo;</h2>
<div>&nbsp;</div>
<div>AI 对现实工作的影响并非 &ldquo;一刀切&rdquo;，而是因<strong>行业属性、岗位价值</strong>的不同呈现出显著的差异化：核心规律是<strong>越偏向机械重复、标准化的行业 / 岗位，受 AI 替代影响越大；越偏向创造性、决策性、人文性的行业 / 岗位，AI 更多是辅助作用，难以被替代</strong>。</div>
<div>&nbsp;</div>
<ol>
<li><strong>受 AI 影响较大的行业 / 岗位</strong>
<div>&nbsp;</div>
主要集中在<strong>服务业、金融、行政、制造业、电商</strong>等行业中的基础岗位，比如客服、数据录入、基础财务、柜台操作、基础编码、基础美工、简单文案等。这类岗位的工作内容规则化程度高，无需复杂的主观判断，AI 能快速实现自动化替代，岗位需求会持续缩减。</li>
<li><strong>AI 以辅助为主，难以替代的行业 / 岗位</strong>
<div>&nbsp;</div>
主要集中在<strong>文化创意、管理决策、教育、医疗、心理咨询、高端服务</strong>等行业，比如作家、设计师、企业管理者、医生、教师、心理咨询师、高端律师等。这类岗位的核心价值在于<strong>人类的创造性、主观判断、情感沟通、战略思维和人文关怀</strong>，而这些能力是当前 AI 难以复刻的 &mdash;&mdash;AI 能生成文案初稿，但无法创造出有深度、有情感的文学作品；AI 能完成影像初诊，但无法做出最终的临床诊断并与患者进行情感沟通；AI 能生成管理建议，但无法结合企业的文化、团队的特点做出战略决策。</li>
<li><strong>AI 推动快速升级的行业 / 岗位</strong>
<div>&nbsp;</div>
主要集中在<strong>互联网、科技、制造业、物流</strong>等技术密集型行业，比如程序员、产品经理、运营、工程师、物流规划师等。这类岗位不会被 AI 替代，但 AI 会成为其核心工作工具，推动岗位能力要求升级 &mdash;&mdash; 从业者需要掌握 AI 工具的使用方法，将 AI 与自身的专业能力结合，实现工作效率和质量的双重提升。</li>
</ol>
<div>&nbsp;</div>
<h2>四、应对趋势：职场人与企业的双向适配</h2>
<div>&nbsp;</div>
<div>面对 AI 对现实工作的深刻影响，无论是职场人还是企业，都无法回避，核心应对思路是 **&ldquo;拥抱 AI、适配 AI，实现人与 AI 的协同工作&rdquo;**，而非 &ldquo;抵制 AI&rdquo; 或 &ldquo;过度依赖 AI&rdquo;。</div>
<div>&nbsp;</div>
<ol>
<li><strong>职场人：树立 &ldquo;AI 协作思维&rdquo;，打造复合型核心能力</strong>
<div>&nbsp;</div>
一方面，要主动学习 AI 工具，掌握与 AI 协作的基本能力 &mdash;&mdash; 比如学会写精准的 prompt、学会审核和优化 AI 的输出结果、学会将 AI 工具融入自身的工作流程，让 AI 成为自己的 &ldquo;工作助手&rdquo;；另一方面，要聚焦于<strong>AI 难以替代的能力培养</strong>，比如创造性思维、战略决策能力、情感沟通能力、跨领域整合能力，打造属于自己的 &ldquo;核心竞争力&rdquo;。同时，要树立 &ldquo;终身学习&rdquo; 的理念，适应 AI 技术的不断更新，避免被行业淘汰。</li>
<li><strong>企业：优化岗位结构，推动 &ldquo;人机协同&rdquo; 的工作模式</strong>
<div>&nbsp;</div>
企业要理性看待 AI 的价值，既不盲目追求 &ldquo;全自动化&rdquo; 而大量裁员，也不忽视 AI 的效率价值。一方面，要结合行业特点和岗位需求，逐步优化岗位结构，将基础重复的工作交给 AI，将人力向高价值、创造性的岗位转移；另一方面，要为员工提供 AI 技能培训，帮助员工快速掌握 AI 工具的使用方法，推动 &ldquo;人机协同&rdquo; 的工作模式落地。同时，企业要建立相关的规范，避免员工过度依赖 AI，保证工作质量。</li>
<li><strong>行业与社会：完善配套机制，缓解 AI 带来的就业压力</strong>
<div>&nbsp;</div>
行业和社会层面，要完善相关的配套机制 &mdash;&mdash; 比如建立 AI 时代的职业技能培训体系，为被 AI 替代的职场人提供转型培训；完善就业保障机制，缓解职场人的职业焦虑；制定 AI 应用的行业规范，避免 AI 的无序发展带来的岗位失衡问题。同时，要鼓励 AI 技术的创新与落地，推动更多新增岗位的出现，实现 &ldquo;岗位替代&rdquo; 与 &ldquo;岗位创造&rdquo; 的平衡。</li>
</ol>]]></description>
    <pubDate>Sat, 28 Feb 2026 17:16:13 +0800</pubDate>
    <dc:creator>neal</dc:creator>
    <guid>https://top.zhongtongzttb.com.cn/?post=85</guid>
</item>
<item>
    <title>怎么使用AI提高软件开发效率</title>
    <link>https://top.zhongtongzttb.com.cn/?post=84</link>
    <description><![CDATA[<div>
<div>
<div>
<div>
<div>
<div>
<div>
<div>
<div>
<div>
<div dir="ltr">
<div>你想了解在编写 Python 爬虫时需要重点关注和注意的事项，这是一个非常关键的问题，尤其是对于新手来说，掌握这些要点能让你的爬虫更合规、更稳定、更高效。</div>
<div>&nbsp;</div>
<h3>一、核心注意事项（按优先级排序）</h3>
<div>&nbsp;</div>
<h4>1. 遵守法律法规与网站规则（最重要）</h4>
<div>&nbsp;</div>
<ul>
<li><strong>robots 协议</strong>：几乎所有网站根目录下都有 <code>robots.txt</code>（如 <code>https://www.xxx.com/robots.txt</code>），它规定了网站允许 / 禁止爬虫访问的内容。虽然不具备法律强制力，但遵守它是爬虫开发者的基本操守。
<div>
<div dir="ltr">
<div>
<div>
<div tabindex="0" aria-describedby="cjet32d">
<div>python</div>
<div>&nbsp;</div>
</div>
<div>
<div>运行</div>
<div tabindex="0" aria-describedby="r1ry2m4">&nbsp;</div>
<div tabindex="0" aria-describedby="sy8ti8s">&nbsp;</div>
<div tabindex="0" aria-describedby="te2cv69">&nbsp;</div>
<div tabindex="0" aria-describedby="0s69ymb">&nbsp;</div>
</div>
</div>
</div>
<div>
<pre tabindex="0"><code># 示例：查看并解析robots.txt（使用robotparser库）
from urllib.robotparser import RobotFileParser

rp = RobotFileParser()
rp.set_url('https://www.baidu.com/robots.txt')
rp.read()
# 检查是否允许爬取某个路径
print(rp.can_fetch('*', 'https://www.baidu.com/s'))  # 返回True/False
</code></pre>
</div>
<div>
<div>&nbsp;</div>
</div>
</div>
</div>
<div>&nbsp;</div>
</li>
<li><strong>法律红线</strong>：
<ul>
<li>不得爬取涉及隐私、敏感信息（如用户手机号、身份证、未公开的商业数据）的内容；</li>
<li>不得突破网站的访问限制（如破解登录、绕过反爬措施进行恶意爬取）；</li>
<li>爬取的数据不得用于非法用途（如倒卖、侵权）。</li>
</ul>
<div>&nbsp;</div>
</li>
<li><strong>网站条款</strong>：很多网站的 &ldquo;用户协议&rdquo; 里明确禁止爬虫，爬取前务必查看。</li>
</ul>
<div>&nbsp;</div>
<h4>2. 控制爬取频率，避免给服务器造成压力</h4>
<div>&nbsp;</div>
<ul>
<li><strong>设置请求间隔</strong>：使用 <code>time.sleep()</code> 或更灵活的 <code>random.uniform()</code> 随机间隔，避免高频请求。
<div>
<div dir="ltr">
<div>
<div>
<div tabindex="0" aria-describedby="6o2thlx">
<div>python</div>
<div>&nbsp;</div>
</div>
<div>
<div>运行</div>
<div tabindex="0" aria-describedby="zpjq7d8">&nbsp;</div>
<div tabindex="0" aria-describedby="xp3ikdo">&nbsp;</div>
<div tabindex="0" aria-describedby="fzs3r5r">&nbsp;</div>
<div tabindex="0" aria-describedby="zv806qu">&nbsp;</div>
</div>
</div>
</div>
<div>
<pre><code>import time
import random

# 每次请求后随机等待1-3秒
time.sleep(random.uniform(1, 3))
</code></pre>
</div>
<div>
<div>&nbsp;</div>
</div>
</div>
</div>
<div>&nbsp;</div>
</li>
<li><strong>限制并发数</strong>：使用 <code>requests.Session()</code> 保持连接复用，或用 <code>aiohttp</code> 异步爬虫时控制并发量（避免同时发起上百个请求）。</li>
<li><strong>避免高峰期爬取</strong>：尽量在网站访问低峰期（如凌晨）爬取，减少对服务器的影响。</li>
</ul>
<div>&nbsp;</div>
<h4>3. 处理反爬机制</h4>
<div>&nbsp;</div>
<div>新手最常遇到的问题就是被网站反爬，核心应对思路是 &ldquo;模拟真人行为&rdquo;：</div>
<div>&nbsp;</div>
<ul>
<li><strong>设置请求头（Headers）</strong>：至少带上 <code>User-Agent</code>（模拟浏览器），必要时补充 <code>Referer</code>、<code>Cookie</code>、<code>Accept</code> 等。
<div>
<div dir="ltr">
<div>
<div>
<div tabindex="0" aria-describedby="gb3qpr3">
<div>python</div>
<div>&nbsp;</div>
</div>
<div>
<div>运行</div>
<div tabindex="0" aria-describedby="i03ujas">&nbsp;</div>
<div tabindex="0" aria-describedby="e3pih1z">&nbsp;</div>
<div tabindex="0" aria-describedby="9hd42x8">&nbsp;</div>
<div tabindex="0" aria-describedby="xf8tzz1">&nbsp;</div>
</div>
</div>
</div>
<div>
<pre><code>import requests

headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36',
    'Referer': 'https://www.xxx.com/'  # 表示请求来源
}
response = requests.get('https://www.xxx.com', headers=headers)
</code></pre>
</div>
<div>
<div>&nbsp;</div>
</div>
</div>
</div>
<div>&nbsp;</div>
</li>
<li><strong>使用代理 IP</strong>：如果爬取量较大，单一 IP 容易被封禁，可使用免费 / 付费代理池轮换 IP。
<div>
<div dir="ltr">
<div>
<div>
<div tabindex="0" aria-describedby="26t0pbh">
<div>python</div>
<div>&nbsp;</div>
</div>
<div>
<div>运行</div>
<div tabindex="0" aria-describedby="etgh1bk">&nbsp;</div>
<div tabindex="0" aria-describedby="a4asd0x">&nbsp;</div>
<div tabindex="0" aria-describedby="tnt8no6">&nbsp;</div>
<div tabindex="0" aria-describedby="hd963ti">&nbsp;</div>
</div>
</div>
</div>
<div>
<pre><code>proxies = {
    'http': 'http://123.45.67.89:8080',
    'https': 'https://123.45.67.89:8080'
}
response = requests.get('https://www.xxx.com', proxies=proxies)
</code></pre>
</div>
<div>
<div>&nbsp;</div>
</div>
</div>
</div>
<div>&nbsp;</div>
</li>
<li><strong>处理验证码</strong>：简单验证码可使用 <code>ddddocr</code> 识别，复杂验证码（滑块、点选）可考虑第三方打码平台，或直接绕开（如模拟登录后携带 Cookie）。</li>
<li><strong>动态渲染页面</strong>：如果页面是 JS 动态加载的（如 Ajax、Vue/React 渲染），可使用 <code>Selenium</code>、<code>Playwright</code> 模拟浏览器渲染，或直接抓包获取接口数据（更高效）。</li>
</ul>
<div>&nbsp;</div>
<h4>4. 代码健壮性与数据处理</h4>
<div>&nbsp;</div>
<ul>
<li><strong>异常处理</strong>：对网络请求、数据解析、文件读写等环节加异常捕获，避免爬虫中途崩溃。
<div>
<div dir="ltr">
<div>
<div>
<div tabindex="0" aria-describedby="yofejkh">
<div>python</div>
<div>&nbsp;</div>
</div>
<div>
<div>运行</div>
<div tabindex="0" aria-describedby="wc4c2gu">&nbsp;</div>
<div tabindex="0" aria-describedby="3n60wwq">&nbsp;</div>
<div tabindex="0" aria-describedby="902cp67">&nbsp;</div>
<div tabindex="0" aria-describedby="2ff1aox">&nbsp;</div>
</div>
</div>
</div>
<div>
<pre><code>import requests
from requests.exceptions import RequestException

try:
    response = requests.get('https://www.xxx.com', timeout=10)
    response.raise_for_status()  # 抛出HTTP状态码异常（如404、500）
    response.encoding = response.apparent_encoding  # 自动识别编码
except RequestException as e:
    print(f'请求失败：{e}')
</code></pre>
</div>
<div>
<div>&nbsp;</div>
</div>
</div>
</div>
<div>&nbsp;</div>
</li>
<li><strong>数据持久化</strong>：爬取的数据及时保存（如 CSV、JSON、MySQL），避免爬取完成后数据丢失。</li>
<li><strong>去重与校验</strong>：对爬取的 URL、数据内容做去重处理，校验数据格式（如手机号、邮箱），保证数据准确性。</li>
</ul>
<div>&nbsp;</div>
<h4>5. 其他实用技巧</h4>
<div>&nbsp;</div>
<ul>
<li><strong>使用 Session 保持会话</strong>：爬取需要登录的网站时，用 <code>requests.Session()</code> 保存 Cookie，避免重复登录。</li>
<li><strong>日志记录</strong>：使用 <code>logging</code> 模块记录爬虫运行日志（如请求成功 / 失败、爬取数量），方便排查问题。
<div>
<div dir="ltr">
<div>
<div>
<div tabindex="0" aria-describedby="jwka2z6">
<div>python</div>
<div>&nbsp;</div>
</div>
<div>
<div>运行</div>
<div tabindex="0" aria-describedby="zauyq8p">&nbsp;</div>
<div tabindex="0" aria-describedby="ui0jzj8">&nbsp;</div>
<div tabindex="0" aria-describedby="qjje0w2">&nbsp;</div>
<div tabindex="0" aria-describedby="2pwvxab">&nbsp;</div>
</div>
</div>
</div>
<div>
<pre><code>import logging

logging.basicConfig(
    level=logging.INFO,
    format='%(asctime)s - %(levelname)s - %(message)s',
    filename='spider.log'  # 日志保存到文件
)
logging.info('爬虫启动')
logging.error('请求失败：IP被封禁')
</code></pre>
</div>
<div>
<div>&nbsp;</div>
</div>
</div>
</div>
<div>&nbsp;</div>
</li>
<li><strong>分布式 / 增量爬取</strong>：如果爬取量极大，可使用 <code>Scrapy-Redis</code> 实现分布式爬虫；定期爬取时，只爬取新增内容（增量爬取），减少资源消耗。</li>
</ul>
<div>&nbsp;</div>
<h3>总结</h3>
<div>&nbsp;</div>
<ol>
<li><strong>合规优先</strong>：遵守 robots 协议和法律法规，不爬取敏感数据，这是爬虫开发的底线；</li>
<li><strong>模拟真人</strong>：控制爬取频率、设置合理请求头、使用代理 IP，避免被网站反爬封禁；</li>
<li><strong>健壮性</strong>：做好异常处理、日志记录和数据持久化，保证爬虫稳定运行且数据不丢失。</li>
</ol>
<div>&nbsp;</div>
<div>掌握这些要点，你的 Python 爬虫不仅能完成基本的爬取任务，还能在合规、稳定、高效上达到更专业的水平。</div>
<div>&nbsp;</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div>
<div>
<div>
<div>
<div>
<div>
<div>
<div>
<div>
<div>
<div>如果用Python来做app自动化测试</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div>
<div>
<div>
<div>
<div>
<div>
<div>
<div>
<div>
<div>
<div dir="ltr">
<div>你想了解如何用 Python 来实现 APP 自动化测试，这是移动端测试中非常实用的技能，Python 凭借丰富的库和简洁的语法，成为 APP 自动化测试的主流选择。</div>
<div>&nbsp;</div>
<h3>一、核心技术栈选择</h3>
<div>&nbsp;</div>
<div>做 APP 自动化测试，Python 生态下最主流的是 <strong>Appium + Python</strong> 组合，它支持 iOS 和 Android 双平台，且能跨应用测试，是行业通用方案。</div>
<div>&nbsp;</div>
<h4>1. 环境准备（关键前置步骤）</h4>
<div>&nbsp;</div>
<div>在写代码前，必须先搭好环境，这是新手最容易踩坑的地方：</div>
<div>&nbsp;</div>
<ul>
<li><strong>基础环境</strong>：Python 3.7+（推荐 3.8-3.10）、pip 包管理工具</li>
<li><strong>移动端依赖</strong>：
<ul>
<li>Android：安装 Android SDK（或 Android Studio），配置<code>ANDROID_HOME</code>环境变量；确保设备 / 模拟器开启 USB 调试</li>
<li>iOS：需 Mac 系统，安装 Xcode、WebDriverAgent</li>
</ul>
<div>&nbsp;</div>
</li>
<li><strong>核心库安装</strong>：
<div>
<div dir="ltr">
<div>
<div>
<div tabindex="0" aria-describedby="gu9ivbh">
<div>bash</div>
<div>&nbsp;</div>
</div>
<div>
<div>运行</div>
<div tabindex="0" aria-describedby="1r32smz">&nbsp;</div>
<div tabindex="0" aria-describedby="2kcbhyr">&nbsp;</div>
<div tabindex="0" aria-describedby="k7hwlnc">&nbsp;</div>
<div tabindex="0" aria-describedby="h4p34j5">&nbsp;</div>
</div>
</div>
</div>
<div>
<pre><code># 安装Appium Python客户端
pip install appium-python-client
# 可选：安装pytest用于测试用例管理，allure用于测试报告
pip install pytest pytest-html allure-pytest
</code></pre>
</div>
<div>
<div>&nbsp;</div>
</div>
</div>
</div>
<div>&nbsp;</div>
</li>
<li><strong>Appium 服务</strong>：下载并安装 Appium Server（或用命令行启动<code>appium</code>），用于连接 Python 脚本和移动设备。</li>
</ul>
<div>&nbsp;</div>
<h4>2. 核心代码示例（Android 端）</h4>
<div>&nbsp;</div>
<div>以下是一个完整的 APP 自动化测试示例（以打开 &ldquo;设置&rdquo; APP，点击 &ldquo;WLAN&rdquo; 为例），包含最核心的元素定位、操作和异常处理：</div>
<div>&nbsp;</div>
<div>
<div dir="ltr">
<div>
<div>
<div tabindex="0" aria-describedby="om17whx">
<div>python</div>
<div>&nbsp;</div>
</div>
<div>
<div>运行</div>
<div tabindex="0" aria-describedby="bdwpgti">&nbsp;</div>
<div tabindex="0" aria-describedby="5xv5sae">&nbsp;</div>
<div tabindex="0" aria-describedby="kyhkpj2">&nbsp;</div>
<div tabindex="0" aria-describedby="4i3tcoy">&nbsp;</div>
</div>
</div>
</div>
<div>
<pre><code>from appium import webdriver
from appium.webdriver.common.appiumby import AppiumBy
from selenium.common.exceptions import NoSuchElementException, TimeoutException
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
import time

# 1. 配置Desired Capabilities（核心配置，告诉Appium要操作的设备/APP）
desired_caps = {
    "platformName": "Android",          # 系统类型：Android/iOS
    "platformVersion": "11",            # 系统版本（如手机的Android版本）
    "deviceName": "emulator-5554",      # 设备名（模拟器/真机序列号，可通过adb devices查看）
    "appPackage": "com.android.settings",  # APP包名（需测试的APP包名）
    "appActivity": ".Settings",         # APP启动页Activity
    "noReset": True,                    # 不重置APP数据（避免每次启动都重新授权）
    "automationName": "UiAutomator2"    # Android自动化引擎（必选）
}

# 2. 初始化驱动，连接Appium服务（默认端口4723）
driver = webdriver.Remote("http://127.0.0.1:4723/wd/hub", desired_caps)
# 设置隐式等待：查找元素时最多等10秒
driver.implicitly_wait(10)

try:
    # 3. 定位元素并操作（以点击&ldquo;WLAN&rdquo;为例）
    # 方式1：通过XPath定位（最通用）
    wlan_element = WebDriverWait(driver, 10).until(
        EC.presence_of_element_located((AppiumBy.XPATH, "//*[@text='WLAN']"))
    )
    wlan_element.click()
    print("成功点击WLAN选项")

    # 额外示例：返回上一页
    driver.back()
    time.sleep(1)

    # 方式2：通过ID定位（更高效，需提前获取元素ID）
    # network_element = driver.find_element(AppiumBy.ID, "com.android.settings:id/network_settings")
    # network_element.click()

except NoSuchElementException:
    print("错误：未找到WLAN元素")
except TimeoutException:
    print("错误：查找WLAN元素超时")
except Exception as e:
    print(f"测试异常：{str(e)}")
finally:
    # 4. 关闭驱动，释放资源
    driver.quit()
    print("测试结束，已关闭驱动")
</code></pre>
</div>
<div>
<div>&nbsp;</div>
</div>
</div>
</div>
<div>&nbsp;</div>
<h4>3. 关键知识点解释</h4>
<div>&nbsp;</div>
<ul>
<li><strong>Desired Capabilities</strong>：是字典格式的配置项，核心参数必须准确，否则无法连接设备 / 启动 APP：
<ul>
<li><code>appPackage</code>/<code>appActivity</code>：Android APP 的核心标识，可通过<code>aapt dump badging 应用包名.apk</code>命令获取；</li>
<li><code>deviceName</code>：通过<code>adb devices</code>命令查看设备列表即可获取；</li>
</ul>
<div>&nbsp;</div>
</li>
<li><strong>元素定位</strong>：APP 自动化的核心是定位控件，常用方式：
<div>
<div>
<table>
<thead>
<tr>
<th>定位方式</th>
<th>适用场景</th>
<th>示例</th>
</tr>
</thead>
<tbody>
<tr>
<td>XPath</td>
<td>通用，无 ID 时优先使用</td>
<td><code>//*[@text='WLAN']</code></td>
</tr>
<tr>
<td>ID</td>
<td>效率最高，优先使用</td>
<td><code>com.android.settings:id/xxx</code></td>
</tr>
<tr>
<td>Accessibility ID</td>
<td>iOS/Android 通用</td>
<td><code>driver.find_element(AppiumBy.ACCESSIBILITY_ID, "WLAN")</code></td>
</tr>
</tbody>
</table>
</div>
</div>
<div>&nbsp;</div>
</li>
<li><strong>等待机制</strong>：
<ul>
<li>隐式等待：全局生效，设置一次即可（如<code>driver.implicitly_wait(10)</code>）；</li>
<li>显式等待：针对特定元素，更灵活（如示例中<code>WebDriverWait</code>），推荐优先使用显式等待，避免元素未加载完成导致的报错。</li>
</ul>
<div>&nbsp;</div>
</li>
</ul>
<div>&nbsp;</div>
<h4>4. 进阶技巧</h4>
<div>&nbsp;</div>
<ul>
<li><strong>APP 安装与启动</strong>：如果需要自动化安装 APP，可在<code>desired_caps</code>中添加<code>"app": "/path/to/xxx.apk"</code>（本地 APK 路径）；</li>
<li><strong>多设备并行测试</strong>：使用<code>appium-python-client</code>结合<code>pytest-xdist</code>实现多设备同时测试，提升效率；</li>
<li><strong>测试报告生成</strong>：用<code>pytest-html</code>生成 HTML 报告，或<code>allure</code>生成更美观的可视化报告；</li>
<li><strong>手势操作</strong>：通过<code>TouchAction</code>或<code>ActionChains</code>实现滑动、点击、长按等操作（如滑动页面找元素）：
<div>
<div dir="ltr">
<div>
<div>
<div tabindex="0" aria-describedby="a2ony0v">
<div>python</div>
<div>&nbsp;</div>
</div>
<div>
<div>运行</div>
<div tabindex="0" aria-describedby="3kpk7zm">&nbsp;</div>
<div tabindex="0" aria-describedby="ssaq5ft">&nbsp;</div>
<div tabindex="0" aria-describedby="zek4vjc">&nbsp;</div>
<div tabindex="0" aria-describedby="0snv9u4">&nbsp;</div>
</div>
</div>
</div>
<div>
<pre><code># 示例：从下往上滑动页面
driver.swipe(start_x=500, start_y=1500, end_x=500, end_y=500, duration=500)
</code></pre>
</div>
<div>
<div>&nbsp;</div>
</div>
</div>
</div>
<div>&nbsp;</div>
</li>
<li><strong>混合应用测试</strong>：如果 APP 包含 H5 页面，需切换到 WebView 上下文，才能定位 H5 元素。</li>
</ul>
<div>&nbsp;</div>
<h3>总结</h3>
<div>&nbsp;</div>
<ol>
<li><strong>核心框架</strong>：Python 做 APP 自动化测试首选<code>Appium + Python</code>，需先配置好 Android/iOS 环境和 Appium 服务；</li>
<li><strong>核心步骤</strong>：配置<code>Desired Capabilities</code> &rarr; 初始化驱动 &rarr; 定位元素 &rarr; 执行操作 &rarr; 异常处理 &rarr; 释放资源；</li>
<li><strong>关键技巧</strong>：优先用显式等待保证稳定性，元素定位优先选 ID（高效），其次用 XPath（通用），做好异常捕获避免脚本崩溃。</li>
</ol>
<div>&nbsp;</div>
<div>掌握这些基础后，你可以结合<code>pytest</code>组织测试用例集，实现批量自动化测试，再配合 CI/CD 工具（如 Jenkins）可实现自动化测试流水线。</div>
<div>&nbsp;</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div>
<div>
<div>
<div>
<div>
<div>
<div>
<div>
<div>
<div>
<div>怎么使用AI提高软件开发效率</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div>
<div>
<div>
<div>
<div>
<div>
<div>
<div>
<div>
<div>
<div dir="ltr">
<div>你想知道如何利用 AI 工具和技术来提升软件开发的整体效率，这是当下开发者最关注的方向之一 &mdash;&mdash;AI 能从编码、调试、文档到协作等全流程帮你节省时间、降低出错率。</div>
<div>&nbsp;</div>
<h3>一、AI 提升开发效率的核心场景（附实操方法）</h3>
<div>&nbsp;</div>
<h4>1. 代码编写：从 &ldquo;从零手写&rdquo; 到 &ldquo;AI 辅助生成&rdquo;</h4>
<div>&nbsp;</div>
<div>AI 能帮你快速生成基础代码、补全逻辑、优化写法，大幅减少重复劳动。</div>
<div>&nbsp;</div>
<ul>
<li><strong>核心工具</strong>：GitHub Copilot（最主流）、Cursor（AI 编辑器）、通义灵码 / 阿里云 AI 编程助手（国内）、ChatGPT / 豆包（对话式生成）。</li>
<li><strong>实操示例</strong>：
<ul>
<li>需求描述式生成：在 Copilot 中输入注释 <code># 用Python写一个函数，批量读取文件夹下所有CSV文件并合并成一个DataFrame，处理空值和重复行</code>，AI 会直接生成完整代码：
<div>
<div dir="ltr">
<div>
<div>
<div tabindex="0" aria-describedby="qa4vq7t">
<div>python</div>
<div>&nbsp;</div>
</div>
<div>
<div>运行</div>
<div tabindex="0" aria-describedby="92o18id">&nbsp;</div>
<div tabindex="0" aria-describedby="5dm5p7p">&nbsp;</div>
<div tabindex="0" aria-describedby="18msvct">&nbsp;</div>
<div tabindex="0" aria-describedby="pulk07j">&nbsp;</div>
</div>
</div>
</div>
<div>
<pre><code>import pandas as pd
import os

def merge_csv_files(folder_path, output_file="merged.csv"):
    """
    批量读取文件夹下所有CSV文件并合并，处理空值和重复行
    :param folder_path: CSV文件所在文件夹路径
    :param output_file: 合并后的输出文件路径
    :return: 合并后的DataFrame
    """
    # 获取文件夹下所有CSV文件
    csv_files = [f for f in os.listdir(folder_path) if f.endswith('.csv')]
    if not csv_files:
        raise ValueError("文件夹中未找到CSV文件")

    # 读取并合并所有CSV
    df_list = []
    for file in csv_files:
        file_path = os.path.join(folder_path, file)
        df = pd.read_csv(file_path)
        df_list.append(df)

    merged_df = pd.concat(df_list, ignore_index=True)
    # 处理空值（删除全为空的行，其余空值填充为0）
    merged_df = merged_df.dropna(how='all')
    merged_df = merged_df.fillna(0)
    # 去重
    merged_df = merged_df.drop_duplicates()

    # 保存结果
    merged_df.to_csv(output_file, index=False)
    return merged_df
</code></pre>
</div>
<div>
<div>&nbsp;</div>
</div>
</div>
</div>
<div>&nbsp;</div>
</li>
<li>代码补全：写一半逻辑（如循环遍历列表），AI 会自动补全剩余代码，甚至优化循环写法（如改用列表推导式）。</li>
</ul>
<div>&nbsp;</div>
</li>
<li><strong>技巧</strong>：描述需求时越具体（如指定语言、框架、功能细节），AI 生成的代码越精准，减少后续修改成本。</li>
</ul>
<div>&nbsp;</div>
<h4>2. 调试与排错：AI 帮你快速定位问题、给出解决方案</h4>
<div>&nbsp;</div>
<div>调试是开发中最耗时的环节之一，AI 能快速分析报错信息、代码逻辑，给出修复建议。</div>
<div>&nbsp;</div>
<ul>
<li><strong>核心工具</strong>：ChatGPT / 豆包（上传报错日志 + 相关代码）、GitHub Copilot Chat、DeepCode（代码静态分析）。</li>
<li><strong>实操示例</strong>：
<div>&nbsp;</div>
你遇到 Python 报错 <code>KeyError: 'name'</code>，将报错信息 + 相关代码发给 AI：
<div>
<div dir="ltr">
<div>
<div>
<div tabindex="0" aria-describedby="ms68jeg">
<div>python</div>
<div>&nbsp;</div>
</div>
<div>
<div>运行</div>
<div tabindex="0" aria-describedby="wcutkwe">&nbsp;</div>
<div tabindex="0" aria-describedby="n3vmveh">&nbsp;</div>
<div tabindex="0" aria-describedby="faxqakk">&nbsp;</div>
<div tabindex="0" aria-describedby="f2l61rv">&nbsp;</div>
</div>
</div>
</div>
<div>
<pre><code># 你的代码
data = {"age": 20}
print(data['name'])
</code></pre>
</div>
<div>
<div>&nbsp;</div>
</div>
</div>
</div>
<div>&nbsp;</div>
AI 会立刻分析：
<ul>
<li>原因：字典<code>data</code>中没有<code>name</code>键，直接取值触发<code>KeyError</code>；</li>
<li>解决方案：① 先判断键是否存在 <code>print(data.get('name', '默认值'))</code>；② 用<code>try-except</code>捕获异常。
<div>&nbsp;</div>
并给出修复后的完整代码：</li>
</ul>
<div>&nbsp;</div>
<div>
<div dir="ltr">
<div>
<div>
<div tabindex="0" aria-describedby="cjkx7wb">
<div>python</div>
<div>&nbsp;</div>
</div>
<div>
<div>运行</div>
<div tabindex="0" aria-describedby="yat8doe">&nbsp;</div>
<div tabindex="0" aria-describedby="t6o07tk">&nbsp;</div>
<div tabindex="0" aria-describedby="lpmgvhm">&nbsp;</div>
<div tabindex="0" aria-describedby="dg8atiq">&nbsp;</div>
</div>
</div>
</div>
<div>
<pre><code>data = {"age": 20}
# 方案1：使用get方法（推荐）
name = data.get('name', '未知')
print(name)  # 输出：未知

# 方案2：try-except捕获异常
try:
    print(data['name'])
except KeyError as e:
    print(f"键不存在：{e}")  # 输出：键不存在：'name'
</code></pre>
</div>
<div>
<div>&nbsp;</div>
</div>
</div>
</div>
<div>&nbsp;</div>
</li>
<li><strong>技巧</strong>：提供报错信息时，务必附上<strong>完整报错堆栈</strong>+<strong>相关代码片段</strong>（不要只发一句 &ldquo;代码报错了&rdquo;），AI 才能精准定位问题。</li>
</ul>
<div>&nbsp;</div>
<h4>3. 文档与注释：AI 自动生成 / 优化文档，降低沟通成本</h4>
<div>&nbsp;</div>
<div>好的文档和注释能提升团队协作效率，但手动编写耗时，AI 可一键生成。</div>
<div>&nbsp;</div>
<ul>
<li><strong>核心工具</strong>：ChatGPT / 豆包、GitHub Copilot（自动生成函数注释）、Docusaurus + AI 插件（文档站点生成）。</li>
<li><strong>实操示例</strong>：
<div>&nbsp;</div>
给一段无注释的复杂函数，让 AI 生成规范的注释：
<div>
<div dir="ltr">
<div>
<div>
<div tabindex="0" aria-describedby="k8dzttu">
<div>python</div>
<div>&nbsp;</div>
</div>
<div>
<div>运行</div>
<div tabindex="0" aria-describedby="nhy52g6">&nbsp;</div>
<div tabindex="0" aria-describedby="cakxrt8">&nbsp;</div>
<div tabindex="0" aria-describedby="ghwz3gy">&nbsp;</div>
<div tabindex="0" aria-describedby="p8fzg7w">&nbsp;</div>
</div>
</div>
</div>
<div>
<pre><code># 无注释的函数
def calculate_order_amount(products, discount_rate=0.1):
    total = sum(p['price'] * p['quantity'] for p in products)
    if total &gt; 1000:
        total *= (1 - discount_rate)
    return round(total, 2)
</code></pre>
</div>
<div>
<div>&nbsp;</div>
</div>
</div>
</div>
<div>&nbsp;</div>
AI 生成的注释（符合 PEP8 规范）：
<div>
<div dir="ltr">
<div>
<div>
<div tabindex="0" aria-describedby="buy5b9k">
<div>python</div>
<div>&nbsp;</div>
</div>
<div>
<div>运行</div>
<div tabindex="0" aria-describedby="zrh5g1y">&nbsp;</div>
<div tabindex="0" aria-describedby="y5oq2mn">&nbsp;</div>
<div tabindex="0" aria-describedby="eyzgq06">&nbsp;</div>
<div tabindex="0" aria-describedby="lqgvn5v">&nbsp;</div>
</div>
</div>
</div>
<div>
<pre><code>def calculate_order_amount(products, discount_rate=0.1):
    """
    计算订单总金额，满1000元享受指定折扣

    :param products: 订单商品列表，每个元素为字典，包含'price'(单价)和'quantity'(数量)键
    :type products: list[dict]
    :param discount_rate: 折扣率（默认0.1，即10%）
    :type discount_rate: float
    :return: 四舍五入到小数点后2位的订单总金额
    :rtype: float
    :example:
        &gt;&gt;&gt; products = [{'price': 100, 'quantity': 5}, {'price': 200, 'quantity': 3}]
        &gt;&gt;&gt; calculate_order_amount(products)
        1080.0
    """
    total = sum(p['price'] * p['quantity'] for p in products)
    if total &gt; 1000:
        total *= (1 - discount_rate)
    return round(total, 2)
</code></pre>
</div>
<div>
<div>&nbsp;</div>
</div>
</div>
</div>
<div>&nbsp;</div>
</li>
<li><strong>技巧</strong>：让 AI 生成文档时，指定格式（如 Markdown、RESTful API 文档规范），便于直接复用。</li>
</ul>
<div>&nbsp;</div>
<h4>4. 需求分析与设计：AI 帮你梳理需求、生成设计方案</h4>
<div>&nbsp;</div>
<div>开发前期的需求梳理和架构设计也能借助 AI 提升效率。</div>
<div>&nbsp;</div>
<ul>
<li><strong>核心工具</strong>：ChatGPT / 豆包（需求转用例、生成 ER 图描述）、Mermaid AI（自动生成流程图 / 架构图）。</li>
<li><strong>实操示例</strong>：
<div>&nbsp;</div>
输入需求：&ldquo;设计一个用户登录模块，包含手机号验证码登录、密码登录，需记录登录日志，限制单日错误次数（5 次）&rdquo;，AI 会帮你：
<ol>
<li>拆解核心功能点（验证码生成 / 校验、密码加密、日志存储、次数限制）；</li>
<li>给出数据库表设计（用户表、登录日志表）；</li>
<li>生成核心接口的设计思路（请求参数、响应格式、异常处理）。</li>
</ol>
<div>&nbsp;</div>
</li>
</ul>
<div>&nbsp;</div>
<h4>5. 测试与重构：AI 辅助生成测试用例、优化代码质量</h4>
<div>&nbsp;</div>
<ul>
<li><strong>测试用例生成</strong>：给 AI 一段业务代码，让其生成单元测试用例（如 pytest 格式），覆盖正常场景、边界场景、异常场景；</li>
<li><strong>代码重构</strong>：让 AI 分析现有代码的问题（如冗余、性能瓶颈、不符合设计模式），并给出重构后的版本（如将重复代码抽成函数、优化循环效率）。</li>
</ul>
<div>&nbsp;</div>
<h3>二、使用 AI 的注意事项（避免踩坑）</h3>
<div>&nbsp;</div>
<ol>
<li><strong>不盲目信任 AI</strong>：AI 生成的代码可能有 bug、安全漏洞或不符合业务逻辑，务必<strong>人工审核 + 测试验证</strong>；</li>
<li><strong>保护敏感信息</strong>：不要将公司核心代码、数据库密码、用户数据等敏感信息输入到公共 AI 工具中；</li>
<li><strong>结合自身知识</strong>：AI 是辅助工具，不是替代开发者，需理解 AI 生成代码的逻辑，避免 &ldquo;抄代码但不懂原理&rdquo;；</li>
<li><strong>选择合适工具</strong>：不同 AI 工具的侧重点不同（如 Copilot 适合编码、ChatGPT 适合调试和文档），按需选择。</li>
</ol>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>]]></description>
    <pubDate>Sat, 28 Feb 2026 17:14:16 +0800</pubDate>
    <dc:creator>neal</dc:creator>
    <guid>https://top.zhongtongzttb.com.cn/?post=84</guid>
</item>
<item>
    <title>如果用Python来做app自动化测试</title>
    <link>https://top.zhongtongzttb.com.cn/?post=83</link>
    <description><![CDATA[<div>
<div>
<div>
<div>
<div>
<div>
<div>
<div>
<div>
<div>
<div>
<div dir="ltr">
<div>你想了解在编写 Python 爬虫时需要重点关注和注意的事项，这是一个非常关键的问题，尤其是对于新手来说，掌握这些要点能让你的爬虫更合规、更稳定、更高效。</div>
<div>&nbsp;</div>
<h3>一、核心注意事项（按优先级排序）</h3>
<div>&nbsp;</div>
<h4>1. 遵守法律法规与网站规则（最重要）</h4>
<div>&nbsp;</div>
<ul>
<li><strong>robots 协议</strong>：几乎所有网站根目录下都有 <code>robots.txt</code>（如 <code>https://www.xxx.com/robots.txt</code>），它规定了网站允许 / 禁止爬虫访问的内容。虽然不具备法律强制力，但遵守它是爬虫开发者的基本操守。
<div>
<div dir="ltr">
<div>
<div>
<div tabindex="0" aria-describedby="cjet32d">
<div>python</div>
<div>&nbsp;</div>
</div>
<div>
<div>运行</div>
<div tabindex="0" aria-describedby="r1ry2m4">&nbsp;</div>
<div tabindex="0" aria-describedby="sy8ti8s">&nbsp;</div>
<div tabindex="0" aria-describedby="te2cv69">&nbsp;</div>
<div tabindex="0" aria-describedby="0s69ymb">&nbsp;</div>
</div>
</div>
</div>
<div>
<pre tabindex="0"><code># 示例：查看并解析robots.txt（使用robotparser库）
from urllib.robotparser import RobotFileParser

rp = RobotFileParser()
rp.set_url('https://www.baidu.com/robots.txt')
rp.read()
# 检查是否允许爬取某个路径
print(rp.can_fetch('*', 'https://www.baidu.com/s'))  # 返回True/False
</code></pre>
</div>
<div>
<div>&nbsp;</div>
</div>
</div>
</div>
<div>&nbsp;</div>
</li>
<li><strong>法律红线</strong>：
<ul>
<li>不得爬取涉及隐私、敏感信息（如用户手机号、身份证、未公开的商业数据）的内容；</li>
<li>不得突破网站的访问限制（如破解登录、绕过反爬措施进行恶意爬取）；</li>
<li>爬取的数据不得用于非法用途（如倒卖、侵权）。</li>
</ul>
<div>&nbsp;</div>
</li>
<li><strong>网站条款</strong>：很多网站的 &ldquo;用户协议&rdquo; 里明确禁止爬虫，爬取前务必查看。</li>
</ul>
<div>&nbsp;</div>
<h4>2. 控制爬取频率，避免给服务器造成压力</h4>
<div>&nbsp;</div>
<ul>
<li><strong>设置请求间隔</strong>：使用 <code>time.sleep()</code> 或更灵活的 <code>random.uniform()</code> 随机间隔，避免高频请求。
<div>
<div dir="ltr">
<div>
<div>
<div tabindex="0" aria-describedby="6o2thlx">
<div>python</div>
<div>&nbsp;</div>
</div>
<div>
<div>运行</div>
<div tabindex="0" aria-describedby="zpjq7d8">&nbsp;</div>
<div tabindex="0" aria-describedby="xp3ikdo">&nbsp;</div>
<div tabindex="0" aria-describedby="fzs3r5r">&nbsp;</div>
<div tabindex="0" aria-describedby="zv806qu">&nbsp;</div>
</div>
</div>
</div>
<div>
<pre><code>import time
import random

# 每次请求后随机等待1-3秒
time.sleep(random.uniform(1, 3))
</code></pre>
</div>
<div>
<div>&nbsp;</div>
</div>
</div>
</div>
<div>&nbsp;</div>
</li>
<li><strong>限制并发数</strong>：使用 <code>requests.Session()</code> 保持连接复用，或用 <code>aiohttp</code> 异步爬虫时控制并发量（避免同时发起上百个请求）。</li>
<li><strong>避免高峰期爬取</strong>：尽量在网站访问低峰期（如凌晨）爬取，减少对服务器的影响。</li>
</ul>
<div>&nbsp;</div>
<h4>3. 处理反爬机制</h4>
<div>&nbsp;</div>
<div>新手最常遇到的问题就是被网站反爬，核心应对思路是 &ldquo;模拟真人行为&rdquo;：</div>
<div>&nbsp;</div>
<ul>
<li><strong>设置请求头（Headers）</strong>：至少带上 <code>User-Agent</code>（模拟浏览器），必要时补充 <code>Referer</code>、<code>Cookie</code>、<code>Accept</code> 等。
<div>
<div dir="ltr">
<div>
<div>
<div tabindex="0" aria-describedby="gb3qpr3">
<div>python</div>
<div>&nbsp;</div>
</div>
<div>
<div>运行</div>
<div tabindex="0" aria-describedby="i03ujas">&nbsp;</div>
<div tabindex="0" aria-describedby="e3pih1z">&nbsp;</div>
<div tabindex="0" aria-describedby="9hd42x8">&nbsp;</div>
<div tabindex="0" aria-describedby="xf8tzz1">&nbsp;</div>
</div>
</div>
</div>
<div>
<pre><code>import requests

headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36',
    'Referer': 'https://www.xxx.com/'  # 表示请求来源
}
response = requests.get('https://www.xxx.com', headers=headers)
</code></pre>
</div>
<div>
<div>&nbsp;</div>
</div>
</div>
</div>
<div>&nbsp;</div>
</li>
<li><strong>使用代理 IP</strong>：如果爬取量较大，单一 IP 容易被封禁，可使用免费 / 付费代理池轮换 IP。
<div>
<div dir="ltr">
<div>
<div>
<div tabindex="0" aria-describedby="26t0pbh">
<div>python</div>
<div>&nbsp;</div>
</div>
<div>
<div>运行</div>
<div tabindex="0" aria-describedby="etgh1bk">&nbsp;</div>
<div tabindex="0" aria-describedby="a4asd0x">&nbsp;</div>
<div tabindex="0" aria-describedby="tnt8no6">&nbsp;</div>
<div tabindex="0" aria-describedby="hd963ti">&nbsp;</div>
</div>
</div>
</div>
<div>
<pre><code>proxies = {
    'http': 'http://123.45.67.89:8080',
    'https': 'https://123.45.67.89:8080'
}
response = requests.get('https://www.xxx.com', proxies=proxies)
</code></pre>
</div>
<div>
<div>&nbsp;</div>
</div>
</div>
</div>
<div>&nbsp;</div>
</li>
<li><strong>处理验证码</strong>：简单验证码可使用 <code>ddddocr</code> 识别，复杂验证码（滑块、点选）可考虑第三方打码平台，或直接绕开（如模拟登录后携带 Cookie）。</li>
<li><strong>动态渲染页面</strong>：如果页面是 JS 动态加载的（如 Ajax、Vue/React 渲染），可使用 <code>Selenium</code>、<code>Playwright</code> 模拟浏览器渲染，或直接抓包获取接口数据（更高效）。</li>
</ul>
<div>&nbsp;</div>
<h4>4. 代码健壮性与数据处理</h4>
<div>&nbsp;</div>
<ul>
<li><strong>异常处理</strong>：对网络请求、数据解析、文件读写等环节加异常捕获，避免爬虫中途崩溃。
<div>
<div dir="ltr">
<div>
<div>
<div tabindex="0" aria-describedby="yofejkh">
<div>python</div>
<div>&nbsp;</div>
</div>
<div>
<div>运行</div>
<div tabindex="0" aria-describedby="wc4c2gu">&nbsp;</div>
<div tabindex="0" aria-describedby="3n60wwq">&nbsp;</div>
<div tabindex="0" aria-describedby="902cp67">&nbsp;</div>
<div tabindex="0" aria-describedby="2ff1aox">&nbsp;</div>
</div>
</div>
</div>
<div>
<pre><code>import requests
from requests.exceptions import RequestException

try:
    response = requests.get('https://www.xxx.com', timeout=10)
    response.raise_for_status()  # 抛出HTTP状态码异常（如404、500）
    response.encoding = response.apparent_encoding  # 自动识别编码
except RequestException as e:
    print(f'请求失败：{e}')
</code></pre>
</div>
<div>
<div>&nbsp;</div>
</div>
</div>
</div>
<div>&nbsp;</div>
</li>
<li><strong>数据持久化</strong>：爬取的数据及时保存（如 CSV、JSON、MySQL），避免爬取完成后数据丢失。</li>
<li><strong>去重与校验</strong>：对爬取的 URL、数据内容做去重处理，校验数据格式（如手机号、邮箱），保证数据准确性。</li>
</ul>
<div>&nbsp;</div>
<h4>5. 其他实用技巧</h4>
<div>&nbsp;</div>
<ul>
<li><strong>使用 Session 保持会话</strong>：爬取需要登录的网站时，用 <code>requests.Session()</code> 保存 Cookie，避免重复登录。</li>
<li><strong>日志记录</strong>：使用 <code>logging</code> 模块记录爬虫运行日志（如请求成功 / 失败、爬取数量），方便排查问题。
<div>
<div dir="ltr">
<div>
<div>
<div tabindex="0" aria-describedby="jwka2z6">
<div>python</div>
<div>&nbsp;</div>
</div>
<div>
<div>运行</div>
<div tabindex="0" aria-describedby="zauyq8p">&nbsp;</div>
<div tabindex="0" aria-describedby="ui0jzj8">&nbsp;</div>
<div tabindex="0" aria-describedby="qjje0w2">&nbsp;</div>
<div tabindex="0" aria-describedby="2pwvxab">&nbsp;</div>
</div>
</div>
</div>
<div>
<pre><code>import logging

logging.basicConfig(
    level=logging.INFO,
    format='%(asctime)s - %(levelname)s - %(message)s',
    filename='spider.log'  # 日志保存到文件
)
logging.info('爬虫启动')
logging.error('请求失败：IP被封禁')
</code></pre>
</div>
<div>
<div>&nbsp;</div>
</div>
</div>
</div>
<div>&nbsp;</div>
</li>
<li><strong>分布式 / 增量爬取</strong>：如果爬取量极大，可使用 <code>Scrapy-Redis</code> 实现分布式爬虫；定期爬取时，只爬取新增内容（增量爬取），减少资源消耗。</li>
</ul>
<div>&nbsp;</div>
<h3>总结</h3>
<div>&nbsp;</div>
<ol>
<li><strong>合规优先</strong>：遵守 robots 协议和法律法规，不爬取敏感数据，这是爬虫开发的底线；</li>
<li><strong>模拟真人</strong>：控制爬取频率、设置合理请求头、使用代理 IP，避免被网站反爬封禁；</li>
<li><strong>健壮性</strong>：做好异常处理、日志记录和数据持久化，保证爬虫稳定运行且数据不丢失。</li>
</ol>
<div>&nbsp;</div>
<div>掌握这些要点，你的 Python 爬虫不仅能完成基本的爬取任务，还能在合规、稳定、高效上达到更专业的水平。</div>
<div>&nbsp;</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div>
<div>
<div>
<div>
<div>
<div>
<div>
<div>
<div>
<div>
<div>如果用Python来做app自动化测试</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div>
<div>
<div>
<div>
<div>
<div>
<div>
<div>
<div>
<div>
<div dir="ltr">
<div>你想了解如何用 Python 来实现 APP 自动化测试，这是移动端测试中非常实用的技能，Python 凭借丰富的库和简洁的语法，成为 APP 自动化测试的主流选择。</div>
<div>&nbsp;</div>
<h3>一、核心技术栈选择</h3>
<div>&nbsp;</div>
<div>做 APP 自动化测试，Python 生态下最主流的是 <strong>Appium + Python</strong> 组合，它支持 iOS 和 Android 双平台，且能跨应用测试，是行业通用方案。</div>
<div>&nbsp;</div>
<h4>1. 环境准备（关键前置步骤）</h4>
<div>&nbsp;</div>
<div>在写代码前，必须先搭好环境，这是新手最容易踩坑的地方：</div>
<div>&nbsp;</div>
<ul>
<li><strong>基础环境</strong>：Python 3.7+（推荐 3.8-3.10）、pip 包管理工具</li>
<li><strong>移动端依赖</strong>：
<ul>
<li>Android：安装 Android SDK（或 Android Studio），配置<code>ANDROID_HOME</code>环境变量；确保设备 / 模拟器开启 USB 调试</li>
<li>iOS：需 Mac 系统，安装 Xcode、WebDriverAgent</li>
</ul>
<div>&nbsp;</div>
</li>
<li><strong>核心库安装</strong>：
<div>
<div dir="ltr">
<div>
<div>
<div tabindex="0" aria-describedby="gu9ivbh">
<div>bash</div>
<div>&nbsp;</div>
</div>
<div>
<div>运行</div>
<div tabindex="0" aria-describedby="1r32smz">&nbsp;</div>
<div tabindex="0" aria-describedby="2kcbhyr">&nbsp;</div>
<div tabindex="0" aria-describedby="k7hwlnc">&nbsp;</div>
<div tabindex="0" aria-describedby="h4p34j5">&nbsp;</div>
</div>
</div>
</div>
<div>
<pre><code># 安装Appium Python客户端
pip install appium-python-client
# 可选：安装pytest用于测试用例管理，allure用于测试报告
pip install pytest pytest-html allure-pytest
</code></pre>
</div>
<div>
<div>&nbsp;</div>
</div>
</div>
</div>
<div>&nbsp;</div>
</li>
<li><strong>Appium 服务</strong>：下载并安装 Appium Server（或用命令行启动<code>appium</code>），用于连接 Python 脚本和移动设备。</li>
</ul>
<div>&nbsp;</div>
<h4>2. 核心代码示例（Android 端）</h4>
<div>&nbsp;</div>
<div>以下是一个完整的 APP 自动化测试示例（以打开 &ldquo;设置&rdquo; APP，点击 &ldquo;WLAN&rdquo; 为例），包含最核心的元素定位、操作和异常处理：</div>
<div>&nbsp;</div>
<div>
<div dir="ltr">
<div>
<div>
<div tabindex="0" aria-describedby="om17whx">
<div>python</div>
<div>&nbsp;</div>
</div>
<div>
<div>运行</div>
<div tabindex="0" aria-describedby="bdwpgti">&nbsp;</div>
<div tabindex="0" aria-describedby="5xv5sae">&nbsp;</div>
<div tabindex="0" aria-describedby="kyhkpj2">&nbsp;</div>
<div tabindex="0" aria-describedby="4i3tcoy">&nbsp;</div>
</div>
</div>
</div>
<div>
<pre><code>from appium import webdriver
from appium.webdriver.common.appiumby import AppiumBy
from selenium.common.exceptions import NoSuchElementException, TimeoutException
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
import time

# 1. 配置Desired Capabilities（核心配置，告诉Appium要操作的设备/APP）
desired_caps = {
    "platformName": "Android",          # 系统类型：Android/iOS
    "platformVersion": "11",            # 系统版本（如手机的Android版本）
    "deviceName": "emulator-5554",      # 设备名（模拟器/真机序列号，可通过adb devices查看）
    "appPackage": "com.android.settings",  # APP包名（需测试的APP包名）
    "appActivity": ".Settings",         # APP启动页Activity
    "noReset": True,                    # 不重置APP数据（避免每次启动都重新授权）
    "automationName": "UiAutomator2"    # Android自动化引擎（必选）
}

# 2. 初始化驱动，连接Appium服务（默认端口4723）
driver = webdriver.Remote("http://127.0.0.1:4723/wd/hub", desired_caps)
# 设置隐式等待：查找元素时最多等10秒
driver.implicitly_wait(10)

try:
    # 3. 定位元素并操作（以点击&ldquo;WLAN&rdquo;为例）
    # 方式1：通过XPath定位（最通用）
    wlan_element = WebDriverWait(driver, 10).until(
        EC.presence_of_element_located((AppiumBy.XPATH, "//*[@text='WLAN']"))
    )
    wlan_element.click()
    print("成功点击WLAN选项")

    # 额外示例：返回上一页
    driver.back()
    time.sleep(1)

    # 方式2：通过ID定位（更高效，需提前获取元素ID）
    # network_element = driver.find_element(AppiumBy.ID, "com.android.settings:id/network_settings")
    # network_element.click()

except NoSuchElementException:
    print("错误：未找到WLAN元素")
except TimeoutException:
    print("错误：查找WLAN元素超时")
except Exception as e:
    print(f"测试异常：{str(e)}")
finally:
    # 4. 关闭驱动，释放资源
    driver.quit()
    print("测试结束，已关闭驱动")
</code></pre>
</div>
<div>
<div>&nbsp;</div>
</div>
</div>
</div>
<div>&nbsp;</div>
<h4>3. 关键知识点解释</h4>
<div>&nbsp;</div>
<ul>
<li><strong>Desired Capabilities</strong>：是字典格式的配置项，核心参数必须准确，否则无法连接设备 / 启动 APP：
<ul>
<li><code>appPackage</code>/<code>appActivity</code>：Android APP 的核心标识，可通过<code>aapt dump badging 应用包名.apk</code>命令获取；</li>
<li><code>deviceName</code>：通过<code>adb devices</code>命令查看设备列表即可获取；</li>
</ul>
<div>&nbsp;</div>
</li>
<li><strong>元素定位</strong>：APP 自动化的核心是定位控件，常用方式：
<div>
<div>
<table>
<thead>
<tr>
<th>定位方式</th>
<th>适用场景</th>
<th>示例</th>
</tr>
</thead>
<tbody>
<tr>
<td>XPath</td>
<td>通用，无 ID 时优先使用</td>
<td><code>//*[@text='WLAN']</code></td>
</tr>
<tr>
<td>ID</td>
<td>效率最高，优先使用</td>
<td><code>com.android.settings:id/xxx</code></td>
</tr>
<tr>
<td>Accessibility ID</td>
<td>iOS/Android 通用</td>
<td><code>driver.find_element(AppiumBy.ACCESSIBILITY_ID, "WLAN")</code></td>
</tr>
</tbody>
</table>
</div>
</div>
<div>&nbsp;</div>
</li>
<li><strong>等待机制</strong>：
<ul>
<li>隐式等待：全局生效，设置一次即可（如<code>driver.implicitly_wait(10)</code>）；</li>
<li>显式等待：针对特定元素，更灵活（如示例中<code>WebDriverWait</code>），推荐优先使用显式等待，避免元素未加载完成导致的报错。</li>
</ul>
<div>&nbsp;</div>
</li>
</ul>
<div>&nbsp;</div>
<h4>4. 进阶技巧</h4>
<div>&nbsp;</div>
<ul>
<li><strong>APP 安装与启动</strong>：如果需要自动化安装 APP，可在<code>desired_caps</code>中添加<code>"app": "/path/to/xxx.apk"</code>（本地 APK 路径）；</li>
<li><strong>多设备并行测试</strong>：使用<code>appium-python-client</code>结合<code>pytest-xdist</code>实现多设备同时测试，提升效率；</li>
<li><strong>测试报告生成</strong>：用<code>pytest-html</code>生成 HTML 报告，或<code>allure</code>生成更美观的可视化报告；</li>
<li><strong>手势操作</strong>：通过<code>TouchAction</code>或<code>ActionChains</code>实现滑动、点击、长按等操作（如滑动页面找元素）：
<div>
<div dir="ltr">
<div>
<div>
<div tabindex="0" aria-describedby="a2ony0v">
<div>python</div>
<div>&nbsp;</div>
</div>
<div>
<div>运行</div>
<div tabindex="0" aria-describedby="3kpk7zm">&nbsp;</div>
<div tabindex="0" aria-describedby="ssaq5ft">&nbsp;</div>
<div tabindex="0" aria-describedby="zek4vjc">&nbsp;</div>
<div tabindex="0" aria-describedby="0snv9u4">&nbsp;</div>
</div>
</div>
</div>
<div>
<pre><code># 示例：从下往上滑动页面
driver.swipe(start_x=500, start_y=1500, end_x=500, end_y=500, duration=500)
</code></pre>
</div>
<div>
<div>&nbsp;</div>
</div>
</div>
</div>
<div>&nbsp;</div>
</li>
<li><strong>混合应用测试</strong>：如果 APP 包含 H5 页面，需切换到 WebView 上下文，才能定位 H5 元素。</li>
</ul>
<div>&nbsp;</div>
<h3>总结</h3>
<div>&nbsp;</div>
<ol>
<li><strong>核心框架</strong>：Python 做 APP 自动化测试首选<code>Appium + Python</code>，需先配置好 Android/iOS 环境和 Appium 服务；</li>
<li><strong>核心步骤</strong>：配置<code>Desired Capabilities</code> &rarr; 初始化驱动 &rarr; 定位元素 &rarr; 执行操作 &rarr; 异常处理 &rarr; 释放资源；</li>
<li><strong>关键技巧</strong>：优先用显式等待保证稳定性，元素定位优先选 ID（高效），其次用 XPath（通用），做好异常捕获避免脚本崩溃。</li>
</ol>
<div>&nbsp;</div>
<div>掌握这些基础后，你可以结合<code>pytest</code>组织测试用例集，实现批量自动化测试，再配合 CI/CD 工具（如 Jenkins）可实现自动化测试流水线。</div>
<div>&nbsp;</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div>
<div>
<div>
<div>&nbsp;</div>
</div>
</div>
</div>]]></description>
    <pubDate>Sat, 28 Feb 2026 17:11:31 +0800</pubDate>
    <dc:creator>neal</dc:creator>
    <guid>https://top.zhongtongzttb.com.cn/?post=83</guid>
</item>
<item>
    <title>Python爬虫有什么值得注意的地方</title>
    <link>https://top.zhongtongzttb.com.cn/?post=82</link>
    <description><![CDATA[<div>你想了解在编写 Python 爬虫时需要重点关注和注意的事项，这是一个非常关键的问题，尤其是对于新手来说，掌握这些要点能让你的爬虫更合规、更稳定、更高效。</div>
<div>&nbsp;</div>
<h3>一、核心注意事项（按优先级排序）</h3>
<div>&nbsp;</div>
<h4>1. 遵守法律法规与网站规则（最重要）</h4>
<div>&nbsp;</div>
<ul>
<li><strong>robots 协议</strong>：几乎所有网站根目录下都有 <code>robots.txt</code>（如 <code>https://www.xxx.com/robots.txt</code>），它规定了网站允许 / 禁止爬虫访问的内容。虽然不具备法律强制力，但遵守它是爬虫开发者的基本操守。
<div>
<div dir="ltr">
<div>
<div>
<div tabindex="0" aria-describedby="cjet32d">
<div>python</div>
<div>&nbsp;</div>
</div>
<div>
<div>运行</div>
<div tabindex="0" aria-describedby="0s69ymb">&nbsp;</div>
</div>
</div>
</div>
<div>
<pre tabindex="0"><code># 示例：查看并解析robots.txt（使用robotparser库）
from urllib.robotparser import RobotFileParser

rp = RobotFileParser()
rp.set_url('https://www.baidu.com/robots.txt')
rp.read()
# 检查是否允许爬取某个路径
print(rp.can_fetch('*', 'https://www.baidu.com/s'))  # 返回True/False
</code></pre>
</div>
<div>
<div>&nbsp;</div>
</div>
</div>
</div>
<div>&nbsp;</div>
</li>
<li><strong>法律红线</strong>：
<ul>
<li>不得爬取涉及隐私、敏感信息（如用户手机号、身份证、未公开的商业数据）的内容；</li>
<li>不得突破网站的访问限制（如破解登录、绕过反爬措施进行恶意爬取）；</li>
<li>爬取的数据不得用于非法用途（如倒卖、侵权）。</li>
</ul>
<div>&nbsp;</div>
</li>
<li><strong>网站条款</strong>：很多网站的 &ldquo;用户协议&rdquo; 里明确禁止爬虫，爬取前务必查看。</li>
</ul>
<div>&nbsp;</div>
<h4>2. 控制爬取频率，避免给服务器造成压力</h4>
<div>&nbsp;</div>
<ul>
<li><strong>设置请求间隔</strong>：使用 <code>time.sleep()</code> 或更灵活的 <code>random.uniform()</code> 随机间隔，避免高频请求。
<div>
<div dir="ltr">
<div>
<div>
<div tabindex="0" aria-describedby="6o2thlx">
<div>python</div>
<div>&nbsp;</div>
</div>
<div>
<div>运行</div>
<div tabindex="0" aria-describedby="zpjq7d8">&nbsp;</div>
<div tabindex="0" aria-describedby="xp3ikdo">&nbsp;</div>
</div>
</div>
</div>
<div>
<pre><code>import time
import random

# 每次请求后随机等待1-3秒
time.sleep(random.uniform(1, 3))
</code></pre>
</div>
<div>
<div>&nbsp;</div>
</div>
</div>
</div>
<div>&nbsp;</div>
</li>
<li><strong>限制并发数</strong>：使用 <code>requests.Session()</code> 保持连接复用，或用 <code>aiohttp</code> 异步爬虫时控制并发量（避免同时发起上百个请求）。</li>
<li><strong>避免高峰期爬取</strong>：尽量在网站访问低峰期（如凌晨）爬取，减少对服务器的影响。</li>
</ul>
<div>&nbsp;</div>
<h4>3. 处理反爬机制</h4>
<div>&nbsp;</div>
<div>新手最常遇到的问题就是被网站反爬，核心应对思路是 &ldquo;模拟真人行为&rdquo;：</div>
<div>&nbsp;</div>
<ul>
<li><strong>设置请求头（Headers）</strong>：至少带上 <code>User-Agent</code>（模拟浏览器），必要时补充 <code>Referer</code>、<code>Cookie</code>、<code>Accept</code> 等。
<div>
<div dir="ltr">
<div>
<div>
<div tabindex="0" aria-describedby="gb3qpr3">
<div>python</div>
<div>&nbsp;</div>
</div>
<div>
<div>运行</div>
<div tabindex="0" aria-describedby="i03ujas">&nbsp;</div>
</div>
</div>
</div>
<div>
<pre><code>import requests

headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36',
    'Referer': 'https://www.xxx.com/'  # 表示请求来源
}
response = requests.get('https://www.xxx.com', headers=headers)
</code></pre>
</div>
<div>
<div>&nbsp;</div>
</div>
</div>
</div>
<div>&nbsp;</div>
</li>
<li><strong>使用代理 IP</strong>：如果爬取量较大，单一 IP 容易被封禁，可使用免费 / 付费代理池轮换 IP。
<div>
<div dir="ltr">
<div>
<div>
<div tabindex="0" aria-describedby="26t0pbh">
<div>python</div>
<div>&nbsp;</div>
</div>
<div>
<div>运行</div>
<div tabindex="0" aria-describedby="etgh1bk">&nbsp;</div>
<div tabindex="0" aria-describedby="a4asd0x">&nbsp;</div>
<div tabindex="0" aria-describedby="tnt8no6">&nbsp;</div>
<div tabindex="0" aria-describedby="hd963ti">&nbsp;</div>
</div>
</div>
</div>
<div>
<pre><code>proxies = {
    'http': 'http://123.45.67.89:8080',
    'https': 'https://123.45.67.89:8080'
}
response = requests.get('https://www.xxx.com', proxies=proxies)
</code></pre>
</div>
<div>
<div>&nbsp;</div>
</div>
</div>
</div>
<div>&nbsp;</div>
</li>
<li><strong>处理验证码</strong>：简单验证码可使用 <code>ddddocr</code> 识别，复杂验证码（滑块、点选）可考虑第三方打码平台，或直接绕开（如模拟登录后携带 Cookie）。</li>
<li><strong>动态渲染页面</strong>：如果页面是 JS 动态加载的（如 Ajax、Vue/React 渲染），可使用 <code>Selenium</code>、<code>Playwright</code> 模拟浏览器渲染，或直接抓包获取接口数据（更高效）。</li>
</ul>
<div>&nbsp;</div>
<h4>4. 代码健壮性与数据处理</h4>
<div>&nbsp;</div>
<ul>
<li><strong>异常处理</strong>：对网络请求、数据解析、文件读写等环节加异常捕获，避免爬虫中途崩溃。
<div>
<div dir="ltr">
<div>
<div>
<div tabindex="0" aria-describedby="yofejkh">
<div>python</div>
<div>&nbsp;</div>
</div>
<div>
<div>运行</div>
<div tabindex="0" aria-describedby="wc4c2gu">&nbsp;</div>
</div>
</div>
</div>
<div>
<pre><code>import requests
from requests.exceptions import RequestException

try:
    response = requests.get('https://www.xxx.com', timeout=10)
    response.raise_for_status()  # 抛出HTTP状态码异常（如404、500）
    response.encoding = response.apparent_encoding  # 自动识别编码
except RequestException as e:
    print(f'请求失败：{e}')
</code></pre>
</div>
<div>
<div>&nbsp;</div>
</div>
</div>
</div>
<div>&nbsp;</div>
</li>
<li><strong>数据持久化</strong>：爬取的数据及时保存（如 CSV、JSON、MySQL），避免爬取完成后数据丢失。</li>
<li><strong>去重与校验</strong>：对爬取的 URL、数据内容做去重处理，校验数据格式（如手机号、邮箱），保证数据准确性。</li>
</ul>
<div>&nbsp;</div>
<h4>5. 其他实用技巧</h4>
<div>&nbsp;</div>
<ul>
<li><strong>使用 Session 保持会话</strong>：爬取需要登录的网站时，用 <code>requests.Session()</code> 保存 Cookie，避免重复登录。</li>
<li><strong>日志记录</strong>：使用 <code>logging</code> 模块记录爬虫运行日志（如请求成功 / 失败、爬取数量），方便排查问题。
<div>
<div dir="ltr">
<div>
<div>
<div tabindex="0" aria-describedby="jwka2z6">
<div>python</div>
<div>&nbsp;</div>
</div>
<div>
<div>运行</div>
<div tabindex="0" aria-describedby="zauyq8p">&nbsp;</div>
<div tabindex="0" aria-describedby="ui0jzj8">&nbsp;</div>
</div>
</div>
</div>
<div>
<pre><code>import logging

logging.basicConfig(
    level=logging.INFO,
    format='%(asctime)s - %(levelname)s - %(message)s',
    filename='spider.log'  # 日志保存到文件
)
logging.info('爬虫启动')
logging.error('请求失败：IP被封禁')
</code></pre>
</div>
<div>
<div>&nbsp;</div>
</div>
</div>
</div>
<div>&nbsp;</div>
</li>
<li><strong>分布式 / 增量爬取</strong>：如果爬取量极大，可使用 <code>Scrapy-Redis</code> 实现分布式爬虫；定期爬取时，只爬取新增内容（增量爬取），减少资源消耗。</li>
</ul>
<div>&nbsp;</div>
<h3>总结</h3>
<div>&nbsp;</div>
<ol>
<li><strong>合规优先</strong>：遵守 robots 协议和法律法规，不爬取敏感数据，这是爬虫开发的底线；</li>
<li><strong>模拟真人</strong>：控制爬取频率、设置合理请求头、使用代理 IP，避免被网站反爬封禁；</li>
<li><strong>健壮性</strong>：做好异常处理、日志记录和数据持久化，保证爬虫稳定运行且数据不丢失。</li>
</ol>]]></description>
    <pubDate>Sat, 28 Feb 2026 13:23:53 +0800</pubDate>
    <dc:creator>neal</dc:creator>
    <guid>https://top.zhongtongzttb.com.cn/?post=82</guid>
</item>
<item>
    <title>乌班图系统怎么部署前后端分离系统</title>
    <link>https://top.zhongtongzttb.com.cn/?post=81</link>
    <description><![CDATA[<p>在Ubuntu系统部署前后端分离系统，核心是分别部署前端静态资源、后端服务，并配置反向代理实现统一访问，以下是通用步骤：<br>&nbsp;<br>1. 准备环境<br>安装所需依赖，如Node.js（前端打包+后端Node服务）、Python/Java/Go（对应后端语言环境）、Nginx（反向代理+静态资源服务）、Docker（可选，容器化部署更便捷）。<br>- 安装Node.js： curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash - &amp;&amp; sudo apt-get install -y nodejs&nbsp;<br>- 安装Nginx： sudo apt update &amp;&amp; sudo apt install nginx&nbsp;<br>2. 部署前端项目<br>- 本地或服务器上打包前端项目（以Vue/React为例）： npm run build ，生成 dist 静态文件夹。<br>- 将 dist 文件夹上传至Ubuntu服务器，推荐路径： /var/www/[项目名]-frontend 。<br>- 配置Nginx指向该静态目录，编辑Nginx配置文件（ /etc/nginx/sites-available/default ），添加：<br>&nbsp;<br>plaintext &nbsp;&nbsp;<br>server {<br>&nbsp; &nbsp; listen 80;<br>&nbsp; &nbsp; server_name 你的服务器IP/域名;</p>
<p>&nbsp; &nbsp; location / {<br>&nbsp; &nbsp; &nbsp; &nbsp; root /var/www/[项目名]-frontend/dist;<br>&nbsp; &nbsp; &nbsp; &nbsp; index index.html;<br>&nbsp; &nbsp; &nbsp; &nbsp; try_files $uri $uri/ /index.html; # 解决前端路由刷新404<br>&nbsp; &nbsp; }<br>}<br>&nbsp;<br>3. 部署后端项目<br>- 若为Node.js后端：上传代码至服务器，安装依赖 npm install --production ，用 pm2 （进程守护工具）启动服务： pm2 start app.js --name [后端服务名] 。<br>- 若为Java后端：打包为 jar 包，上传后用 nohup java -jar [xxx.jar] &amp; 后台运行；或用 systemd 配置开机自启。<br>- 确保后端服务监听指定端口（如 3000 ），且服务器防火墙/安全组开放该端口。<br>4. 配置Nginx反向代理（关键）<br>为解决跨域问题，在Nginx配置中添加后端接口代理规则，示例：<br>plaintext &nbsp;&nbsp;<br>server {<br>&nbsp; &nbsp; listen 80;<br>&nbsp; &nbsp; server_name 你的服务器IP/域名;</p>
<p>&nbsp; &nbsp; # 前端静态资源<br>&nbsp; &nbsp; location / {<br>&nbsp; &nbsp; &nbsp; &nbsp; root /var/www/[项目名]-frontend/dist;<br>&nbsp; &nbsp; &nbsp; &nbsp; index index.html;<br>&nbsp; &nbsp; &nbsp; &nbsp; try_files $uri $uri/ /index.html;<br>&nbsp; &nbsp; }</p>
<p>&nbsp; &nbsp; # 后端接口代理<br>&nbsp; &nbsp; location /api {<br>&nbsp; &nbsp; &nbsp; &nbsp; proxy_pass http://127.0.0.1:3000; # 后端服务地址+端口<br>&nbsp; &nbsp; &nbsp; &nbsp; proxy_set_header Host $host;<br>&nbsp; &nbsp; &nbsp; &nbsp; proxy_set_header X-Real-IP $remote_addr;<br>&nbsp; &nbsp; }<br>}<br>&nbsp;<br>&nbsp;<br>配置完成后，重启Nginx生效： sudo nginx -t &amp;&amp; sudo systemctl restart nginx&nbsp;<br>5. 验证部署<br>浏览器访问服务器IP/域名，能正常加载前端页面，且前端调用 /api 接口可成功获取后端数据，即部署完成。<br>&nbsp;</p>]]></description>
    <pubDate>Mon, 29 Dec 2025 10:03:14 +0800</pubDate>
    <dc:creator>neal</dc:creator>
    <guid>https://top.zhongtongzttb.com.cn/?post=81</guid>
</item>
<item>
    <title>怎么在Ubuntu系统部署项目</title>
    <link>https://top.zhongtongzttb.com.cn/?post=79</link>
    <description><![CDATA[<div class="inter-H_fm37">
<div class="container-PvPoAn">
<div class="item-kDun2N">
<div class="container-SrVXPg chrome70-container">
<div class="inner-Qo5lJS inner-item-w21SQO" data-target-id="message-box-target-id" data-testid="union_message">
<div class="message-block-container-PggqdK" data-testid="message-block-container" data-ui-version="samantha">
<div class="flex flex-row w-full w-full max-w-full s-font-base text-s-color-text-secondary p-0 rounded-s-radius-s bg-transparent group data-[attr=select-mode]:-mt-10 data-[attr=select-mode]:py-10 data-[attr=select-mode]:px-16 data-[attr=select-mode]:sm:p-10 data-[attr=select-mode]:hover:bg-s-color-bg-base data-[attr=select-mode]:hover:rounded-s-radius-xs data-[attr=select-mode]:has-[:checked]:bg-s-color-bg-trans data-[attr=select-mode]:has-[:checked]:rounded-s-radius-xs data-[attr=select-mode]:pointer-events-none" data-testid="receive_message" data-copy-telemetry="right_click_copy">
<div class="flex flex-col flex-grow max-w-full min-w-0">
<div class="flex-row flex w-full" data-testid="message_content" data-message-id="33688965386609922">
<div class="flex w-full flex-col [&amp;&gt;div:not(:last-child):not(:empty)]:mb-20" style="outline: none; -webkit-font-smoothing: antialiased; box-sizing: border-box; -webkit-tap-highlight-color: rgba(0, 0, 0, 0); border: 0px solid; margin: 0px; padding: 0px; --desktop-home-page-background-color: #f4f4f4; --desktop-home-card-background-color: #fdfdfd; --desktop-home-card-background-color-hover: #fff; --desktop-home-popup-background-color: #f6f5f5; display: flex; width: 793px; flex-direction: column; overflow-anchor: auto;">
<div class="" data-render-engine="node" data-plugin-identifier="block_type:10000">
<div class="container-P2rR72 flow-markdown-body mdbox-theme-next theme-samantha-uDexJL" dir="ltr" data-testid="message_text_content" data-show-indicator="false">
<div class="auto-hide-last-sibling-br paragraph-pP9ZLC paragraph-element br-paragraph-space">在 Ubuntu 系统部署项目是一个综合性操作，核心流程随项目类型（前端 / 后端 / 静态 / 动态）略有差异，但整体遵循<strong>环境准备 &rarr; 代码部署 &rarr; 服务配置 &rarr; 访问测试 &rarr; 运维保障</strong>&nbsp;的逻辑。以下按「通用流程 + 不同项目类型实操」展开，覆盖最常见的 Web 项目场景（前端、Python/Java/Node.js 后端、静态站点）。</div>
<h3 class="header-iWP5WJ auto-hide-last-sibling-br">一、部署前准备（通用步骤）</h3>
<h4 class="header-iWP5WJ auto-hide-last-sibling-br">1. 服务器基础配置（首次部署必做）</h4>
<div class="code-block-element-R6c8c0 light custom-code-block-container--bash hide-indicator disable-theme-style custom-code-block-container">
<div class="code-area-yxsM36 code-area" dir="ltr">
<div class="header-wrapper-Mbk8s6">
<div class="header-IAeXdE">
<div class="title-TXcgFG clickable-cKrA4B" tabindex="0" aria-describedby="cf1koms" data-popupid="cf1koms">
<div class="text-OkYU_0">bash</div>
<div class="icon-UKNQeW">&nbsp;</div>
</div>
<div class="action-ysQCxz">
<div class="hoverable-kRHiX2">运行</div>
<div class="hoverable-kRHiX2" tabindex="0" data-testid="code-block-preview" aria-describedby="ardr7vm" data-popupid="ardr7vm">&nbsp;</div>
</div>
</div>
</div>
<div class="content-y8qlFa code-content light-scrollbar-FFk5j5">
<pre class="container-S2LAkl language-bash" tabindex="0"><code># 1. 更新系统包
sudo apt update &amp;&amp; sudo apt upgrade -y

# 2. 安装基础工具（必备）
sudo apt install -y git wget curl vim unzip # git拉代码、vim编辑文件、解压等
</code></pre>
</div>
<div class="mask-wrapper-ujeSdZ">
<div class="mask-lrkkzM">&nbsp;</div>
</div>
</div>
</div>
<h4 class="header-iWP5WJ auto-hide-last-sibling-br">2. 权限与目录规划（规范部署）</h4>
<div class="auto-hide-last-sibling-br paragraph-pP9ZLC paragraph-element br-paragraph-space">建议统一将项目放在&nbsp;<code>/var/www/</code>（Web 项目）或&nbsp;<code>/opt/</code>（非 Web 项目）目录，避免直接用 root 运行项目：</div>
<div class="container-Uxvbjy md-box-line-break wrapper-GYqxgQ undefined">&nbsp;</div>
<div class="code-block-element-R6c8c0 light custom-code-block-container--bash hide-indicator disable-theme-style custom-code-block-container">
<div class="code-area-yxsM36 code-area" dir="ltr">
<div class="header-wrapper-Mbk8s6">
<div class="header-IAeXdE">
<div class="title-TXcgFG clickable-cKrA4B" tabindex="0" aria-describedby="nxazmbt" data-popupid="nxazmbt">
<div class="text-OkYU_0">bash</div>
<div class="icon-UKNQeW">&nbsp;</div>
</div>
<div class="action-ysQCxz">
<div class="hoverable-kRHiX2">运行</div>
<div class="hoverable-kRHiX2" tabindex="0" data-testid="code-block-preview" aria-describedby="y3mbseg" data-popupid="y3mbseg">&nbsp;</div>
</div>
</div>
</div>
<div class="content-y8qlFa code-content light-scrollbar-FFk5j5">
<pre class="container-S2LAkl language-bash"><code># 创建项目目录（以/var/www为例）
sudo mkdir -p /var/www/your-project
# 设置普通用户权限（假设当前用户为ubuntu）
sudo chown -R ubuntu:ubuntu /var/www/your-project
</code></pre>
</div>
<div class="mask-wrapper-ujeSdZ">
<div class="mask-lrkkzM">&nbsp;</div>
</div>
</div>
</div>
<h4 class="header-iWP5WJ auto-hide-last-sibling-br">3. 拉取代码（Git 方式，最常用）</h4>
<div class="code-block-element-R6c8c0 light custom-code-block-container--bash hide-indicator disable-theme-style custom-code-block-container">
<div class="code-area-yxsM36 code-area" dir="ltr">
<div class="header-wrapper-Mbk8s6">
<div class="header-IAeXdE">
<div class="title-TXcgFG clickable-cKrA4B" tabindex="0" aria-describedby="w89xho0" data-popupid="w89xho0">
<div class="text-OkYU_0">bash</div>
<div class="icon-UKNQeW">&nbsp;</div>
</div>
<div class="action-ysQCxz">
<div class="hoverable-kRHiX2">运行</div>
<div class="hoverable-kRHiX2" tabindex="0" data-testid="code-block-preview" aria-describedby="4do03k3" data-popupid="4do03k3">&nbsp;</div>
</div>
</div>
</div>
<div class="content-y8qlFa code-content light-scrollbar-FFk5j5">
<pre class="container-S2LAkl language-bash"><code># 进入项目目录
cd /var/www/your-project
# 克隆代码仓库（GitHub/GitLab/Gitee）
git clone https://github.com/your-name/your-project.git . # 加.表示克隆到当前目录
# 若需指定分支
git clone -b dev https://github.com/your-name/your-project.git .
</code></pre>
</div>
<div class="mask-wrapper-ujeSdZ">
<div class="mask-lrkkzM">&nbsp;</div>
</div>
</div>
</div>
<div class="container-Uxvbjy md-box-line-break wrapper-GYqxgQ undefined">&nbsp;</div>
<blockquote>
<div class="auto-hide-last-sibling-br paragraph-pP9ZLC paragraph-element br-paragraph-space">若没有 Git 仓库，可通过&nbsp;<code>scp</code>&nbsp;或&nbsp;<code>rz/sz</code>（需安装&nbsp;<code>lrzsz</code>）上传代码包，再解压：</div>
<div class="container-Uxvbjy md-box-line-break wrapper-GYqxgQ undefined">&nbsp;</div>
<div class="code-block-element-R6c8c0 light custom-code-block-container--bash hide-indicator disable-theme-style custom-code-block-container">
<div class="code-area-yxsM36 code-area" dir="ltr">
<div class="header-wrapper-Mbk8s6">
<div class="header-IAeXdE">
<div class="title-TXcgFG clickable-cKrA4B" tabindex="0" aria-describedby="2h93gzo" data-popupid="2h93gzo">
<div class="text-OkYU_0">bash</div>
<div class="icon-UKNQeW">&nbsp;</div>
</div>
<div class="action-ysQCxz">
<div class="hoverable-kRHiX2">运行</div>
<div class="hoverable-kRHiX2" tabindex="0" data-testid="code-block-preview" aria-describedby="q8vqen0" data-popupid="q8vqen0">&nbsp;</div>
</div>
</div>
</div>
<div class="content-y8qlFa code-content light-scrollbar-FFk5j5">
<pre class="container-S2LAkl language-bash"><code>unzip your-project.zip # 解压zip包
tar -zxvf your-project.tar.gz # 解压tar.gz包
</code></pre>
</div>
<div class="mask-wrapper-ujeSdZ">
<div class="mask-lrkkzM">&nbsp;</div>
</div>
</div>
</div>
<div class="container-Uxvbjy md-box-line-break wrapper-GYqxgQ undefined">&nbsp;</div>
</blockquote>
<h3 class="header-iWP5WJ auto-hide-last-sibling-br">二、不同类型项目部署实操</h3>
<h4 class="header-iWP5WJ auto-hide-last-sibling-br">场景 1：静态项目（Vue/React/HTML/CSS/JS）</h4>
<div class="auto-hide-last-sibling-br paragraph-pP9ZLC paragraph-element br-paragraph-space">静态项目仅需<strong>Web 服务器（Nginx/Apache）</strong>&nbsp;提供文件访问，核心是配置 Nginx 指向静态文件目录。</div>
<h5 class="header-iWP5WJ auto-hide-last-sibling-br">步骤 1：安装 Nginx</h5>
<div class="code-block-element-R6c8c0 light custom-code-block-container--bash hide-indicator disable-theme-style custom-code-block-container">
<div class="code-area-yxsM36 code-area" dir="ltr">
<div class="header-wrapper-Mbk8s6">
<div class="header-IAeXdE">
<div class="title-TXcgFG clickable-cKrA4B" tabindex="0" aria-describedby="kjdstkr" data-popupid="kjdstkr">
<div class="text-OkYU_0">bash</div>
<div class="icon-UKNQeW">&nbsp;</div>
</div>
<div class="action-ysQCxz">
<div class="hoverable-kRHiX2">运行</div>
<div class="hoverable-kRHiX2" tabindex="0" aria-describedby="3b7a841" data-popupid="3b7a841">&nbsp;</div>
<div class="hoverable-kRHiX2" tabindex="0" data-testid="code-block-preview" aria-describedby="43fhykc" data-popupid="43fhykc">&nbsp;</div>
</div>
</div>
</div>
<div class="content-y8qlFa code-content light-scrollbar-FFk5j5">
<pre class="container-S2LAkl language-bash"><code>sudo apt install -y nginx
# 启动并设置开机自启
sudo systemctl start nginx
sudo systemctl enable nginx
# 验证是否启动成功（访问服务器IP，能看到Nginx默认页则成功）
</code></pre>
</div>
<div class="mask-wrapper-ujeSdZ">
<div class="mask-lrkkzM">&nbsp;</div>
</div>
</div>
</div>
<h5 class="header-iWP5WJ auto-hide-last-sibling-br">步骤 2：构建静态文件（前端项目需打包）</h5>
<div class="code-block-element-R6c8c0 light custom-code-block-container--bash hide-indicator disable-theme-style custom-code-block-container">
<div class="code-area-yxsM36 code-area" dir="ltr">
<div class="header-wrapper-Mbk8s6">
<div class="header-IAeXdE">
<div class="title-TXcgFG clickable-cKrA4B" tabindex="0" aria-describedby="r4cb3tt" data-popupid="r4cb3tt">
<div class="text-OkYU_0">bash</div>
<div class="icon-UKNQeW">&nbsp;</div>
</div>
<div class="action-ysQCxz">
<div class="hoverable-kRHiX2">运行</div>
<div class="hoverable-kRHiX2" tabindex="0" aria-describedby="q1ega1m" data-popupid="q1ega1m">&nbsp;</div>
<div class="hoverable-kRHiX2" tabindex="0" data-testid="code-block-preview" aria-describedby="zqmrrov" data-popupid="zqmrrov">&nbsp;</div>
</div>
</div>
</div>
<div class="content-y8qlFa code-content light-scrollbar-FFk5j5">
<pre class="container-S2LAkl language-bash"><code># 进入项目目录
cd /var/www/your-project
# 安装依赖（需先装Node.js，见下方）
npm install
# 打包生成dist目录（Vue/React通用，若有自定义打包命令则用自己的）
npm run build
</code></pre>
</div>
<div class="mask-wrapper-ujeSdZ">
<div class="mask-lrkkzM">&nbsp;</div>
</div>
</div>
</div>
<h5 class="header-iWP5WJ auto-hide-last-sibling-br">步骤 3：配置 Nginx 站点</h5>
<div class="code-block-element-R6c8c0 light custom-code-block-container--bash hide-indicator disable-theme-style custom-code-block-container">
<div class="code-area-yxsM36 code-area" dir="ltr">
<div class="header-wrapper-Mbk8s6">
<div class="header-IAeXdE">
<div class="title-TXcgFG clickable-cKrA4B" tabindex="0" aria-describedby="ght8j49" data-popupid="ght8j49">
<div class="text-OkYU_0">bash</div>
<div class="icon-UKNQeW">&nbsp;</div>
</div>
<div class="action-ysQCxz">
<div class="hoverable-kRHiX2">运行</div>
<div class="hoverable-kRHiX2" tabindex="0" data-testid="code-block-copy" aria-describedby="81zg29x" data-popupid="81zg29x">&nbsp;</div>
</div>
</div>
</div>
<div class="content-y8qlFa code-content light-scrollbar-FFk5j5">
<pre class="container-S2LAkl language-bash"><code># 创建Nginx配置文件（自定义名称，如your-project.conf）
sudo vim /etc/nginx/sites-available/your-project.conf
</code></pre>
</div>
<div class="mask-wrapper-ujeSdZ">
<div class="mask-lrkkzM">&nbsp;</div>
</div>
</div>
</div>
<div class="container-Uxvbjy md-box-line-break wrapper-GYqxgQ undefined">&nbsp;</div>
<div class="auto-hide-last-sibling-br paragraph-pP9ZLC paragraph-element br-paragraph-space">写入以下配置（替换&nbsp;<code>your-domain.com</code>&nbsp;为域名 / 服务器 IP，<code>/var/www/your-project/dist</code>&nbsp;为实际打包目录）：</div>
<div class="container-Uxvbjy md-box-line-break wrapper-GYqxgQ undefined">&nbsp;</div>
<div class="code-block-element-R6c8c0 light custom-code-block-container--nginx hide-indicator disable-theme-style custom-code-block-container">
<div class="code-area-yxsM36 code-area" dir="ltr">
<div class="header-wrapper-Mbk8s6">
<div class="header-IAeXdE">
<div class="title-TXcgFG clickable-cKrA4B" tabindex="0" aria-describedby="nfj7h08" data-popupid="nfj7h08">
<div class="text-OkYU_0">nginx</div>
<div class="icon-UKNQeW">&nbsp;</div>
</div>
</div>
</div>
<div class="content-y8qlFa code-content light-scrollbar-FFk5j5">
<pre class="container-S2LAkl language-nginx"><code>server {
    listen 80; # 监听80端口
    server_name your-domain.com; # 域名/IP

    # 静态文件根目录（dist为打包后的目录）
    root /var/www/your-project/dist;
    index index.html index.htm;

    # 解决Vue/React路由刷新404问题
    location / {
        try_files $uri $uri/ /index.html;
    }

    # 静态资源缓存（可选）
    location ~* \.(js|css|png|jpg|jpeg|gif|ico)$ {
        expires 30d;
        add_header Cache-Control "public, max-age=2592000";
    }
}
</code></pre>
</div>
<div class="mask-wrapper-ujeSdZ">
<div class="mask-lrkkzM">&nbsp;</div>
</div>
</div>
</div>
<h5 class="header-iWP5WJ auto-hide-last-sibling-br">步骤 4：启用配置并重启 Nginx</h5>
<div class="code-block-element-R6c8c0 light custom-code-block-container--bash hide-indicator disable-theme-style custom-code-block-container">
<div class="code-area-yxsM36 code-area" dir="ltr">
<div class="header-wrapper-Mbk8s6">
<div class="header-IAeXdE">
<div class="title-TXcgFG clickable-cKrA4B" tabindex="0" aria-describedby="acvfx0r" data-popupid="acvfx0r">
<div class="text-OkYU_0">bash</div>
<div class="icon-UKNQeW">&nbsp;</div>
</div>
<div class="action-ysQCxz">
<div class="hoverable-kRHiX2">运行</div>
<div class="hoverable-kRHiX2" tabindex="0" data-testid="code-block-copy" aria-describedby="fm6gyrk" data-popupid="fm6gyrk">&nbsp;</div>
</div>
</div>
</div>
<div class="content-y8qlFa code-content light-scrollbar-FFk5j5">
<pre class="container-S2LAkl language-bash"><code># 启用站点（创建软链接到sites-enabled）
sudo ln -s /etc/nginx/sites-available/your-project.conf /etc/nginx/sites-enabled/
# 检查配置语法
sudo nginx -t
# 重启Nginx
sudo systemctl restart nginx
</code></pre>
</div>
<div class="mask-wrapper-ujeSdZ">
<div class="mask-lrkkzM">&nbsp;</div>
</div>
</div>
</div>
<h5 class="header-iWP5WJ auto-hide-last-sibling-br">步骤 5：访问测试</h5>
<div class="auto-hide-last-sibling-br paragraph-pP9ZLC paragraph-element br-paragraph-space">浏览器输入&nbsp;<code>http://服务器IP</code>&nbsp;或&nbsp;<code>http://your-domain.com</code>，即可访问静态项目。</div>
<h4 class="header-iWP5WJ auto-hide-last-sibling-br">场景 2：Python 后端项目（Django/Flask/FastAPI）</h4>
<div class="auto-hide-last-sibling-br paragraph-pP9ZLC paragraph-element br-paragraph-space">Python 项目需<strong>Python 环境 + 依赖安装 + WSGI/ASGI 服务器（Gunicorn/Uvicorn） + Nginx 反向代理</strong>（对外提供访问）。</div>
<h5 class="header-iWP5WJ auto-hide-last-sibling-br">步骤 1：安装 Python 环境</h5>
<div class="code-block-element-R6c8c0 light custom-code-block-container--bash hide-indicator disable-theme-style custom-code-block-container">
<div class="code-area-yxsM36 code-area" dir="ltr">
<div class="header-wrapper-Mbk8s6">
<div class="header-IAeXdE">
<div class="title-TXcgFG clickable-cKrA4B" tabindex="0" aria-describedby="f2w0fzv" data-popupid="f2w0fzv">
<div class="text-OkYU_0">bash</div>
<div class="icon-UKNQeW">&nbsp;</div>
</div>
<div class="action-ysQCxz">
<div class="hoverable-kRHiX2">运行</div>
<div class="hoverable-kRHiX2" tabindex="0" data-testid="code-block-preview" aria-describedby="sovk1f7" data-popupid="sovk1f7">&nbsp;</div>
</div>
</div>
</div>
<div class="content-y8qlFa code-content light-scrollbar-FFk5j5">
<pre class="container-S2LAkl language-bash"><code># 安装Python3及虚拟环境（推荐用虚拟环境隔离依赖）
sudo apt install -y python3 python3-pip python3-venv
# 创建虚拟环境
cd /var/www/your-project
python3 -m venv venv
# 激活虚拟环境
source venv/bin/activate
</code></pre>
</div>
<div class="mask-wrapper-ujeSdZ">
<div class="mask-lrkkzM">&nbsp;</div>
</div>
</div>
</div>
<h5 class="header-iWP5WJ auto-hide-last-sibling-br">步骤 2：安装项目依赖</h5>
<div class="code-block-element-R6c8c0 light custom-code-block-container--bash hide-indicator disable-theme-style custom-code-block-container">
<div class="code-area-yxsM36 code-area" dir="ltr">
<div class="header-wrapper-Mbk8s6">
<div class="header-IAeXdE">
<div class="title-TXcgFG clickable-cKrA4B" tabindex="0" aria-describedby="l4bf0kp" data-popupid="l4bf0kp">
<div class="text-OkYU_0">bash</div>
<div class="icon-UKNQeW">&nbsp;</div>
</div>
<div class="action-ysQCxz">
<div class="hoverable-kRHiX2">运行</div>
<div class="hoverable-kRHiX2" tabindex="0" data-testid="code-block-preview" aria-describedby="j5o4bcq" data-popupid="j5o4bcq">&nbsp;</div>
</div>
</div>
</div>
<div class="content-y8qlFa code-content light-scrollbar-FFk5j5">
<pre class="container-S2LAkl language-bash"><code># 安装依赖（requirements.txt为项目依赖文件）
pip install -r requirements.txt
# 安装WSGI/ASGI服务器（Django/Flask用Gunicorn，FastAPI用Uvicorn）
pip install gunicorn # Django/Flask
# pip install uvicorn[standard] # FastAPI
</code></pre>
</div>
<div class="mask-wrapper-ujeSdZ">
<div class="mask-lrkkzM">&nbsp;</div>
</div>
</div>
</div>
<h5 class="header-iWP5WJ auto-hide-last-sibling-br">步骤 3：测试项目运行</h5>
<div class="code-block-element-R6c8c0 light custom-code-block-container--bash hide-indicator disable-theme-style custom-code-block-container">
<div class="code-area-yxsM36 code-area" dir="ltr">
<div class="header-wrapper-Mbk8s6">
<div class="header-IAeXdE">
<div class="title-TXcgFG clickable-cKrA4B" tabindex="0" aria-describedby="mxsgjo0" data-popupid="mxsgjo0">
<div class="text-OkYU_0">bash</div>
<div class="icon-UKNQeW">&nbsp;</div>
</div>
<div class="action-ysQCxz">
<div class="hoverable-kRHiX2">运行</div>
<div class="hoverable-kRHiX2" tabindex="0" aria-describedby="ikn6p6s" data-popupid="ikn6p6s">&nbsp;</div>
<div class="hoverable-kRHiX2" tabindex="0" data-testid="code-block-preview" aria-describedby="e2qg7c7" data-popupid="e2qg7c7">&nbsp;</div>
</div>
</div>
</div>
<div class="content-y8qlFa code-content light-scrollbar-FFk5j5">
<pre class="container-S2LAkl language-bash"><code># Django测试
python manage.py runserver 0.0.0.0:8000
# Flask测试（假设入口文件为app.py，启动函数为app）
python app.py
# FastAPI测试（假设入口文件为main.py，启动函数为app）
uvicorn main:app --host 0.0.0.0 --port 8000
</code></pre>
</div>
<div class="mask-wrapper-ujeSdZ">
<div class="mask-lrkkzM">&nbsp;</div>
</div>
</div>
</div>
<div class="container-Uxvbjy md-box-line-break wrapper-GYqxgQ undefined">&nbsp;</div>
<blockquote class="auto-hide-last-sibling-br">
<div class="auto-hide-last-sibling-br paragraph-pP9ZLC paragraph-element br-paragraph-space">测试通过后，按&nbsp;<code>Ctrl+C</code>&nbsp;停止，下一步用守护进程运行。</div>
</blockquote>
<h5 class="header-iWP5WJ auto-hide-last-sibling-br">步骤 4：配置 Systemd 守护进程（保证项目后台运行）</h5>
<div class="code-block-element-R6c8c0 light custom-code-block-container--bash hide-indicator disable-theme-style custom-code-block-container">
<div class="code-area-yxsM36 code-area" dir="ltr">
<div class="header-wrapper-Mbk8s6">
<div class="header-IAeXdE">
<div class="title-TXcgFG clickable-cKrA4B" tabindex="0" aria-describedby="ecgezaa" data-popupid="ecgezaa">
<div class="text-OkYU_0">bash</div>
<div class="icon-UKNQeW">&nbsp;</div>
</div>
<div class="action-ysQCxz">
<div class="hoverable-kRHiX2">运行</div>
<div class="hoverable-kRHiX2" tabindex="0" data-testid="code-block-copy" aria-describedby="g3sk860" data-popupid="g3sk860">&nbsp;</div>
<div class="hoverable-kRHiX2" tabindex="0" aria-describedby="uf6w6j0" data-popupid="uf6w6j0">&nbsp;</div>
<div class="hoverable-kRHiX2" tabindex="0" aria-describedby="lfhfd5a" data-popupid="lfhfd5a">&nbsp;</div>
<div class="hoverable-kRHiX2" tabindex="0" data-testid="code-block-preview" aria-describedby="j7hw4z2" data-popupid="j7hw4z2">&nbsp;</div>
</div>
</div>
</div>
<div class="content-y8qlFa code-content light-scrollbar-FFk5j5">
<pre class="container-S2LAkl language-bash"><code># 创建systemd服务文件（命名为your-project.service）
sudo vim /etc/systemd/system/your-project.service
</code></pre>
</div>
<div class="mask-wrapper-ujeSdZ">
<div class="mask-lrkkzM">&nbsp;</div>
</div>
</div>
</div>
<div class="container-Uxvbjy md-box-line-break wrapper-GYqxgQ undefined">&nbsp;</div>
<div class="auto-hide-last-sibling-br paragraph-pP9ZLC paragraph-element br-paragraph-space">写入以下配置（替换路径 / 参数为实际值）：</div>
<div class="container-Uxvbjy md-box-line-break wrapper-GYqxgQ undefined">&nbsp;</div>
<div class="code-block-element-R6c8c0 light custom-code-block-container--ini hide-indicator disable-theme-style custom-code-block-container">
<div class="code-area-yxsM36 code-area" dir="ltr">
<div class="header-wrapper-Mbk8s6">
<div class="header-IAeXdE">
<div class="title-TXcgFG clickable-cKrA4B" tabindex="0" aria-describedby="e6k4w4c" data-popupid="e6k4w4c">
<div class="text-OkYU_0">ini</div>
<div class="icon-UKNQeW">&nbsp;</div>
</div>
<div class="action-ysQCxz">
<div class="hoverable-kRHiX2" tabindex="0" data-testid="code-block-copy" aria-describedby="2jsy81o" data-popupid="2jsy81o">&nbsp;</div>
<div class="hoverable-kRHiX2" tabindex="0" aria-describedby="6vl3xo4" data-popupid="6vl3xo4">&nbsp;</div>
<div class="hoverable-kRHiX2" tabindex="0" aria-describedby="g2ji9s8" data-popupid="g2ji9s8">&nbsp;</div>
<div class="hoverable-kRHiX2" tabindex="0" data-testid="code-block-preview" aria-describedby="9awrbca" data-popupid="9awrbca">&nbsp;</div>
</div>
</div>
</div>
<div class="content-y8qlFa code-content light-scrollbar-FFk5j5">
<pre class="container-S2LAkl language-ini"><code>[Unit]
Description=Python Project (Gunicorn/Uvicorn)
After=network.target

[Service]
User=ubuntu # 运行用户（非root）
Group=ubuntu
WorkingDirectory=/var/www/your-project # 项目目录
ExecStart=/var/www/your-project/venv/bin/gunicorn --workers 4 --bind 127.0.0.1:8000 wsgi:application # Django/Flask
# ExecStart=/var/www/your-project/venv/bin/uvicorn main:app --workers 4 --bind 127.0.0.1:8000 # FastAPI
Restart=always # 进程崩溃自动重启

[Install]
WantedBy=multi-user.target
</code></pre>
</div>
<div class="mask-wrapper-ujeSdZ">
<div class="mask-lrkkzM">&nbsp;</div>
</div>
</div>
</div>
<div class="container-Uxvbjy md-box-line-break wrapper-GYqxgQ undefined">&nbsp;</div>
<blockquote class="auto-hide-last-sibling-br">
<div class="auto-hide-last-sibling-br paragraph-pP9ZLC paragraph-element br-paragraph-space">说明：</div>
<div class="container-Uxvbjy md-box-line-break wrapper-GYqxgQ undefined">&nbsp;</div>
<ul class="auto-hide-last-sibling-br">
<li>Django 的&nbsp;<code>wsgi.py</code>&nbsp;入口：<code>wsgi:application</code>（默认在项目根目录的 wsgi.py）；</li>
<li>Flask 需先创建 wsgi.py：<code>from app import app as application</code>，再指向&nbsp;<code>wsgi:application</code>；</li>
<li><code>--workers 4</code>：工作进程数，建议设为&nbsp;<code>CPU核心数*2+1</code>。</li>
</ul>
</blockquote>
<h5 class="header-iWP5WJ auto-hide-last-sibling-br">步骤 5：启动服务并设置开机自启</h5>
<div class="code-block-element-R6c8c0 light custom-code-block-container--bash hide-indicator disable-theme-style custom-code-block-container">
<div class="code-area-yxsM36 code-area" dir="ltr">
<div class="header-wrapper-Mbk8s6">
<div class="header-IAeXdE">
<div class="title-TXcgFG clickable-cKrA4B" tabindex="0" aria-describedby="h5tugtw" data-popupid="h5tugtw">
<div class="text-OkYU_0">bash</div>
<div class="icon-UKNQeW">&nbsp;</div>
</div>
<div class="action-ysQCxz">
<div class="hoverable-kRHiX2">运行</div>
<div class="hoverable-kRHiX2" tabindex="0" data-testid="code-block-copy" aria-describedby="6t3lkz6" data-popupid="6t3lkz6">&nbsp;</div>
<div class="hoverable-kRHiX2" tabindex="0" aria-describedby="jrzmkdv" data-popupid="jrzmkdv">&nbsp;</div>
<div class="hoverable-kRHiX2" tabindex="0" aria-describedby="h632bky" data-popupid="h632bky">&nbsp;</div>
<div class="hoverable-kRHiX2" tabindex="0" data-testid="code-block-preview" aria-describedby="dp56k5h" data-popupid="dp56k5h">&nbsp;</div>
</div>
</div>
</div>
<div class="content-y8qlFa code-content light-scrollbar-FFk5j5">
<pre class="container-S2LAkl language-bash"><code># 重新加载systemd配置
sudo systemctl daemon-reload
# 启动服务
sudo systemctl start your-project
# 设置开机自启
sudo systemctl enable your-project
# 查看服务状态（确认无报错）
sudo systemctl status your-project
</code></pre>
</div>
<div class="mask-wrapper-ujeSdZ">
<div class="mask-lrkkzM">&nbsp;</div>
</div>
</div>
</div>
<h5 class="header-iWP5WJ auto-hide-last-sibling-br">步骤 6：配置 Nginx 反向代理（对外暴露 80 端口）</h5>
<div class="code-block-element-R6c8c0 light custom-code-block-container--bash hide-indicator disable-theme-style custom-code-block-container">
<div class="code-area-yxsM36 code-area" dir="ltr">
<div class="header-wrapper-Mbk8s6">
<div class="header-IAeXdE">
<div class="title-TXcgFG clickable-cKrA4B" tabindex="0" aria-describedby="hfd62z5" data-popupid="hfd62z5">
<div class="text-OkYU_0">bash</div>
<div class="icon-UKNQeW">&nbsp;</div>
</div>
<div class="action-ysQCxz">
<div class="hoverable-kRHiX2">运行</div>
<div class="hoverable-kRHiX2" tabindex="0" data-testid="code-block-copy" aria-describedby="1opm3o0" data-popupid="1opm3o0">&nbsp;</div>
<div class="hoverable-kRHiX2" tabindex="0" aria-describedby="imyrddc" data-popupid="imyrddc">&nbsp;</div>
<div class="hoverable-kRHiX2" tabindex="0" aria-describedby="juvc1hk" data-popupid="juvc1hk">&nbsp;</div>
<div class="hoverable-kRHiX2" tabindex="0" data-testid="code-block-preview" aria-describedby="x4grar7" data-popupid="x4grar7">&nbsp;</div>
</div>
</div>
</div>
<div class="content-y8qlFa code-content light-scrollbar-FFk5j5">
<pre class="container-S2LAkl language-bash"><code>sudo vim /etc/nginx/sites-available/your-project.conf
</code></pre>
</div>
<div class="mask-wrapper-ujeSdZ">
<div class="mask-lrkkzM">&nbsp;</div>
</div>
</div>
</div>
<div class="container-Uxvbjy md-box-line-break wrapper-GYqxgQ undefined">&nbsp;</div>
<div class="auto-hide-last-sibling-br paragraph-pP9ZLC paragraph-element br-paragraph-space">写入配置：</div>
<div class="container-Uxvbjy md-box-line-break wrapper-GYqxgQ undefined">&nbsp;</div>
<div class="code-block-element-R6c8c0 light custom-code-block-container--nginx hide-indicator disable-theme-style custom-code-block-container">
<div class="code-area-yxsM36 code-area" dir="ltr">
<div class="header-wrapper-Mbk8s6">
<div class="header-IAeXdE">
<div class="title-TXcgFG clickable-cKrA4B" tabindex="0" aria-describedby="parmhhr" data-popupid="parmhhr">
<div class="text-OkYU_0">nginx</div>
<div class="icon-UKNQeW">&nbsp;</div>
</div>
<div class="action-ysQCxz">
<div class="hoverable-kRHiX2" tabindex="0" data-testid="code-block-copy" aria-describedby="x76p7bb" data-popupid="x76p7bb">&nbsp;</div>
<div class="hoverable-kRHiX2" tabindex="0" aria-describedby="2zvuxzi" data-popupid="2zvuxzi">&nbsp;</div>
<div class="hoverable-kRHiX2" tabindex="0" aria-describedby="pb0d8ul" data-popupid="pb0d8ul">&nbsp;</div>
<div class="hoverable-kRHiX2" tabindex="0" data-testid="code-block-preview" aria-describedby="6d1wp9l" data-popupid="6d1wp9l">&nbsp;</div>
</div>
</div>
</div>
<div class="content-y8qlFa code-content light-scrollbar-FFk5j5">
<pre class="container-S2LAkl language-nginx"><code>server {
    listen 80;
    server_name your-domain.com;

    # 反向代理到Python服务
    location / {
        proxy_pass http://127.0.0.1:8000;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }

    # 静态文件（Django需配置，Flask/FastAPI若有静态文件也需加）
    location /static/ {
        root /var/www/your-project; # Django静态文件根目录
        expires 30d;
    }
}
</code></pre>
</div>
<div class="mask-wrapper-ujeSdZ">
<div class="mask-lrkkzM">&nbsp;</div>
</div>
</div>
</div>
<h5 class="header-iWP5WJ auto-hide-last-sibling-br">步骤 7：启用配置并重启 Nginx</h5>
<div class="code-block-element-R6c8c0 light custom-code-block-container--bash hide-indicator disable-theme-style custom-code-block-container">
<div class="code-area-yxsM36 code-area" dir="ltr">
<div class="header-wrapper-Mbk8s6">
<div class="header-IAeXdE">
<div class="title-TXcgFG clickable-cKrA4B" tabindex="0" aria-describedby="2hy5xil" data-popupid="2hy5xil">
<div class="text-OkYU_0">bash</div>
<div class="icon-UKNQeW">&nbsp;</div>
</div>
<div class="action-ysQCxz">
<div class="hoverable-kRHiX2">运行</div>
<div class="hoverable-kRHiX2" tabindex="0" data-testid="code-block-copy" aria-describedby="73m71qa" data-popupid="73m71qa">&nbsp;</div>
<div class="hoverable-kRHiX2" tabindex="0" aria-describedby="pejgg4r" data-popupid="pejgg4r">&nbsp;</div>
<div class="hoverable-kRHiX2" tabindex="0" aria-describedby="4s0fx3v" data-popupid="4s0fx3v">&nbsp;</div>
<div class="hoverable-kRHiX2" tabindex="0" data-testid="code-block-preview" aria-describedby="8yef5ov" data-popupid="8yef5ov">&nbsp;</div>
</div>
</div>
</div>
<div class="content-y8qlFa code-content light-scrollbar-FFk5j5">
<pre class="container-S2LAkl language-bash"><code>sudo ln -s /etc/nginx/sites-available/your-project.conf /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl restart nginx
</code></pre>
</div>
<div class="mask-wrapper-ujeSdZ">
<div class="mask-lrkkzM">&nbsp;</div>
</div>
</div>
</div>
<h5 class="header-iWP5WJ auto-hide-last-sibling-br">步骤 8：访问测试</h5>
<div class="auto-hide-last-sibling-br paragraph-pP9ZLC paragraph-element br-paragraph-space">浏览器输入&nbsp;<code>http://服务器IP</code>&nbsp;或&nbsp;<code>http://your-domain.com</code>，即可访问 Python 后端接口。</div>
<h4 class="header-iWP5WJ auto-hide-last-sibling-br">场景 3：Java 后端项目（Spring Boot）</h4>
<div class="auto-hide-last-sibling-br paragraph-pP9ZLC paragraph-element br-paragraph-space">Java 项目需<strong>JDK 环境 + 运行 Jar 包 + Systemd 守护进程 + Nginx 反向代理</strong>（可选，若需 80 端口访问）。</div>
<h5 class="header-iWP5WJ auto-hide-last-sibling-br">步骤 1：安装 JDK</h5>
<div class="code-block-element-R6c8c0 light custom-code-block-container--bash hide-indicator disable-theme-style custom-code-block-container">
<div class="code-area-yxsM36 code-area" dir="ltr">
<div class="header-wrapper-Mbk8s6">
<div class="header-IAeXdE">
<div class="title-TXcgFG clickable-cKrA4B" tabindex="0" aria-describedby="uymsfrx" data-popupid="uymsfrx">
<div class="text-OkYU_0">bash</div>
<div class="icon-UKNQeW">&nbsp;</div>
</div>
<div class="action-ysQCxz">
<div class="hoverable-kRHiX2">运行</div>
<div class="hoverable-kRHiX2" tabindex="0" data-testid="code-block-copy" aria-describedby="y6trsuq" data-popupid="y6trsuq">&nbsp;</div>
<div class="hoverable-kRHiX2" tabindex="0" aria-describedby="k3m8sl4" data-popupid="k3m8sl4">&nbsp;</div>
<div class="hoverable-kRHiX2" tabindex="0" aria-describedby="6ahp29a" data-popupid="6ahp29a">&nbsp;</div>
<div class="hoverable-kRHiX2" tabindex="0" data-testid="code-block-preview" aria-describedby="wc1k9ai" data-popupid="wc1k9ai">&nbsp;</div>
</div>
</div>
</div>
<div class="content-y8qlFa code-content light-scrollbar-FFk5j5">
<pre class="container-S2LAkl language-bash"><code># 安装OpenJDK（推荐11/17，适配Spring Boot）
sudo apt install -y openjdk-17-jdk
# 验证安装
java -version
javac -version
</code></pre>
</div>
<div class="mask-wrapper-ujeSdZ">
<div class="mask-lrkkzM">&nbsp;</div>
</div>
</div>
</div>
<h5 class="header-iWP5WJ auto-hide-last-sibling-br">步骤 2：运行 Jar 包（测试）</h5>
<div class="code-block-element-R6c8c0 light custom-code-block-container--bash hide-indicator disable-theme-style custom-code-block-container">
<div class="code-area-yxsM36 code-area" dir="ltr">
<div class="header-wrapper-Mbk8s6">
<div class="header-IAeXdE">
<div class="title-TXcgFG clickable-cKrA4B" tabindex="0" aria-describedby="qj5lsz3" data-popupid="qj5lsz3">
<div class="text-OkYU_0">bash</div>
<div class="icon-UKNQeW">&nbsp;</div>
</div>
<div class="action-ysQCxz">
<div class="hoverable-kRHiX2">运行</div>
<div class="hoverable-kRHiX2" tabindex="0" data-testid="code-block-copy" aria-describedby="69x9e3d" data-popupid="69x9e3d">&nbsp;</div>
<div class="hoverable-kRHiX2" tabindex="0" aria-describedby="zretjxt" data-popupid="zretjxt">&nbsp;</div>
<div class="hoverable-kRHiX2" tabindex="0" aria-describedby="2dmd0r8" data-popupid="2dmd0r8">&nbsp;</div>
<div class="hoverable-kRHiX2" tabindex="0" data-testid="code-block-preview" aria-describedby="8g6jt69" data-popupid="8g6jt69">&nbsp;</div>
</div>
</div>
</div>
<div class="content-y8qlFa code-content light-scrollbar-FFk5j5">
<pre class="container-S2LAkl language-bash"><code>cd /var/www/your-project
# 测试运行（假设Jar包为your-project.jar）
java -jar your-project.jar
</code></pre>
</div>
<div class="mask-wrapper-ujeSdZ">
<div class="mask-lrkkzM">&nbsp;</div>
</div>
</div>
</div>
<div class="container-Uxvbjy md-box-line-break wrapper-GYqxgQ undefined">&nbsp;</div>
<blockquote class="auto-hide-last-sibling-br">
<div class="auto-hide-last-sibling-br paragraph-pP9ZLC paragraph-element br-paragraph-space">测试通过后，按&nbsp;<code>Ctrl+C</code>&nbsp;停止，配置后台运行。</div>
</blockquote>
<h5 class="header-iWP5WJ auto-hide-last-sibling-br">步骤 3：配置 Systemd 守护进程</h5>
<div class="code-block-element-R6c8c0 light custom-code-block-container--bash hide-indicator disable-theme-style custom-code-block-container">
<div class="code-area-yxsM36 code-area" dir="ltr">
<div class="header-wrapper-Mbk8s6">
<div class="header-IAeXdE">
<div class="title-TXcgFG clickable-cKrA4B" tabindex="0" aria-describedby="0qumfk8" data-popupid="0qumfk8">
<div class="text-OkYU_0">bash</div>
<div class="icon-UKNQeW">&nbsp;</div>
</div>
<div class="action-ysQCxz">
<div class="hoverable-kRHiX2">运行</div>
<div class="hoverable-kRHiX2" tabindex="0" data-testid="code-block-copy" aria-describedby="r0yf60o" data-popupid="r0yf60o">&nbsp;</div>
<div class="hoverable-kRHiX2" tabindex="0" aria-describedby="nd7csrj" data-popupid="nd7csrj">&nbsp;</div>
<div class="hoverable-kRHiX2" tabindex="0" aria-describedby="hep5f08" data-popupid="hep5f08">&nbsp;</div>
<div class="hoverable-kRHiX2" tabindex="0" data-testid="code-block-preview" aria-describedby="kfv3i3g" data-popupid="kfv3i3g">&nbsp;</div>
</div>
</div>
</div>
<div class="content-y8qlFa code-content light-scrollbar-FFk5j5">
<pre class="container-S2LAkl language-bash"><code>sudo vim /etc/systemd/system/your-project.service
</code></pre>
</div>
<div class="mask-wrapper-ujeSdZ">
<div class="mask-lrkkzM">&nbsp;</div>
</div>
</div>
</div>
<div class="container-Uxvbjy md-box-line-break wrapper-GYqxgQ undefined">&nbsp;</div>
<div class="auto-hide-last-sibling-br paragraph-pP9ZLC paragraph-element br-paragraph-space">写入配置：</div>
<div class="container-Uxvbjy md-box-line-break wrapper-GYqxgQ undefined">&nbsp;</div>
<div class="code-block-element-R6c8c0 light custom-code-block-container--ini hide-indicator disable-theme-style custom-code-block-container">
<div class="code-area-yxsM36 code-area" dir="ltr">
<div class="header-wrapper-Mbk8s6">
<div class="header-IAeXdE">
<div class="title-TXcgFG clickable-cKrA4B" tabindex="0" aria-describedby="0wjz9rm" data-popupid="0wjz9rm">
<div class="text-OkYU_0">ini</div>
<div class="icon-UKNQeW">&nbsp;</div>
</div>
<div class="action-ysQCxz">
<div class="hoverable-kRHiX2" tabindex="0" data-testid="code-block-copy" aria-describedby="b83304l" data-popupid="b83304l">&nbsp;</div>
<div class="hoverable-kRHiX2" tabindex="0" aria-describedby="6vg9a5w" data-popupid="6vg9a5w">&nbsp;</div>
<div class="hoverable-kRHiX2" tabindex="0" aria-describedby="n6zmkbf" data-popupid="n6zmkbf">&nbsp;</div>
<div class="hoverable-kRHiX2" tabindex="0" data-testid="code-block-preview" aria-describedby="ck552j7" data-popupid="ck552j7">&nbsp;</div>
</div>
</div>
</div>
<div class="content-y8qlFa code-content light-scrollbar-FFk5j5">
<pre class="container-S2LAkl language-ini"><code>[Unit]
Description=Spring Boot Project
After=network.target

[Service]
User=ubuntu
Group=ubuntu
WorkingDirectory=/var/www/your-project
ExecStart=/usr/bin/java -jar your-project.jar --server.port=8080 # 指定端口
Restart=always
# 可选：设置JVM参数
# ExecStart=/usr/bin/java -Xms512m -Xmx1024m -jar your-project.jar --server.port=8080

[Install]
WantedBy=multi-user.target
</code></pre>
</div>
<div class="mask-wrapper-ujeSdZ">
<div class="mask-lrkkzM">&nbsp;</div>
</div>
</div>
</div>
<h5 class="header-iWP5WJ auto-hide-last-sibling-br">步骤 4：启动服务并设置开机自启</h5>
<div class="code-block-element-R6c8c0 light custom-code-block-container--bash hide-indicator disable-theme-style custom-code-block-container">
<div class="code-area-yxsM36 code-area" dir="ltr">
<div class="header-wrapper-Mbk8s6">
<div class="header-IAeXdE">
<div class="title-TXcgFG clickable-cKrA4B" tabindex="0" aria-describedby="48uibkx" data-popupid="48uibkx">
<div class="text-OkYU_0">bash</div>
<div class="icon-UKNQeW">&nbsp;</div>
</div>
<div class="action-ysQCxz">
<div class="hoverable-kRHiX2">运行</div>
<div class="hoverable-kRHiX2" tabindex="0" data-testid="code-block-copy" aria-describedby="6i4fn2e" data-popupid="6i4fn2e">&nbsp;</div>
<div class="hoverable-kRHiX2" tabindex="0" aria-describedby="to9yyeh" data-popupid="to9yyeh">&nbsp;</div>
<div class="hoverable-kRHiX2" tabindex="0" aria-describedby="m65d5na" data-popupid="m65d5na">&nbsp;</div>
<div class="hoverable-kRHiX2" tabindex="0" data-testid="code-block-preview" aria-describedby="le9u22k" data-popupid="le9u22k">&nbsp;</div>
</div>
</div>
</div>
<div class="content-y8qlFa code-content light-scrollbar-FFk5j5">
<pre class="container-S2LAkl language-bash"><code>sudo systemctl daemon-reload
sudo systemctl start your-project
sudo systemctl enable your-project
sudo systemctl status your-project
</code></pre>
</div>
<div class="mask-wrapper-ujeSdZ">
<div class="mask-lrkkzM">&nbsp;</div>
</div>
</div>
</div>
<h5 class="header-iWP5WJ auto-hide-last-sibling-br">步骤 5：配置 Nginx 反向代理（可选，暴露 80 端口）</h5>
<div class="code-block-element-R6c8c0 light custom-code-block-container--bash hide-indicator disable-theme-style custom-code-block-container">
<div class="code-area-yxsM36 code-area" dir="ltr">
<div class="header-wrapper-Mbk8s6">
<div class="header-IAeXdE">
<div class="title-TXcgFG clickable-cKrA4B" tabindex="0" aria-describedby="6c91xfr" data-popupid="6c91xfr">
<div class="text-OkYU_0">bash</div>
<div class="icon-UKNQeW">&nbsp;</div>
</div>
<div class="action-ysQCxz">
<div class="hoverable-kRHiX2">运行</div>
<div class="hoverable-kRHiX2" tabindex="0" data-testid="code-block-copy" aria-describedby="2svps48" data-popupid="2svps48">&nbsp;</div>
<div class="hoverable-kRHiX2" tabindex="0" aria-describedby="llzhiox" data-popupid="llzhiox">&nbsp;</div>
<div class="hoverable-kRHiX2" tabindex="0" aria-describedby="b0ljpr7" data-popupid="b0ljpr7">&nbsp;</div>
<div class="hoverable-kRHiX2" tabindex="0" data-testid="code-block-preview" aria-describedby="aapa1bu" data-popupid="aapa1bu">&nbsp;</div>
</div>
</div>
</div>
<div class="content-y8qlFa code-content light-scrollbar-FFk5j5">
<pre class="container-S2LAkl language-bash"><code>sudo vim /etc/nginx/sites-available/your-project.conf
</code></pre>
</div>
<div class="mask-wrapper-ujeSdZ">
<div class="mask-lrkkzM">&nbsp;</div>
</div>
</div>
</div>
<div class="container-Uxvbjy md-box-line-break wrapper-GYqxgQ undefined">&nbsp;</div>
<div class="auto-hide-last-sibling-br paragraph-pP9ZLC paragraph-element br-paragraph-space">写入配置：</div>
<div class="container-Uxvbjy md-box-line-break wrapper-GYqxgQ undefined">&nbsp;</div>
<div class="code-block-element-R6c8c0 light custom-code-block-container--nginx hide-indicator disable-theme-style custom-code-block-container">
<div class="code-area-yxsM36 code-area" dir="ltr">
<div class="header-wrapper-Mbk8s6">
<div class="header-IAeXdE">
<div class="title-TXcgFG clickable-cKrA4B" tabindex="0" aria-describedby="sbxpsg8" data-popupid="sbxpsg8">
<div class="text-OkYU_0">nginx</div>
<div class="icon-UKNQeW">&nbsp;</div>
</div>
<div class="action-ysQCxz">
<div class="hoverable-kRHiX2" tabindex="0" data-testid="code-block-copy" aria-describedby="x39nb0z" data-popupid="x39nb0z">&nbsp;</div>
<div class="hoverable-kRHiX2" tabindex="0" aria-describedby="yvvj365" data-popupid="yvvj365">&nbsp;</div>
<div class="hoverable-kRHiX2" tabindex="0" aria-describedby="ziisa4b" data-popupid="ziisa4b">&nbsp;</div>
<div class="hoverable-kRHiX2" tabindex="0" data-testid="code-block-preview" aria-describedby="v78qvc3" data-popupid="v78qvc3">&nbsp;</div>
</div>
</div>
</div>
<div class="content-y8qlFa code-content light-scrollbar-FFk5j5">
<pre class="container-S2LAkl language-nginx"><code>server {
    listen 80;
    server_name your-domain.com;

    location / {
        proxy_pass http://127.0.0.1:8080;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
}
</code></pre>
</div>
<div class="mask-wrapper-ujeSdZ">
<div class="mask-lrkkzM">&nbsp;</div>
</div>
</div>
</div>
<div class="container-Uxvbjy md-box-line-break wrapper-GYqxgQ undefined">&nbsp;</div>
<div class="auto-hide-last-sibling-br paragraph-pP9ZLC paragraph-element br-paragraph-space">启用配置并重启 Nginx 后，即可通过&nbsp;<code>http://服务器IP</code>&nbsp;访问。</div>
<h3 class="header-iWP5WJ auto-hide-last-sibling-br">三、部署后运维（必做）</h3>
<h4 class="header-iWP5WJ auto-hide-last-sibling-br">1. 日志查看（排错必备）</h4>
<div class="code-block-element-R6c8c0 light custom-code-block-container--bash hide-indicator disable-theme-style custom-code-block-container">
<div class="code-area-yxsM36 code-area" dir="ltr">
<div class="header-wrapper-Mbk8s6">
<div class="header-IAeXdE">
<div class="title-TXcgFG clickable-cKrA4B" tabindex="0" aria-describedby="ob47f6k" data-popupid="ob47f6k">
<div class="text-OkYU_0">bash</div>
<div class="icon-UKNQeW">&nbsp;</div>
</div>
<div class="action-ysQCxz">
<div class="hoverable-kRHiX2">运行</div>
<div class="hoverable-kRHiX2" tabindex="0" data-testid="code-block-copy" aria-describedby="m2578sm" data-popupid="m2578sm">&nbsp;</div>
<div class="hoverable-kRHiX2" tabindex="0" aria-describedby="9jrba02" data-popupid="9jrba02">&nbsp;</div>
<div class="hoverable-kRHiX2" tabindex="0" aria-describedby="2cz9r3t" data-popupid="2cz9r3t">&nbsp;</div>
<div class="hoverable-kRHiX2" tabindex="0" data-testid="code-block-preview" aria-describedby="8v70vqn" data-popupid="8v70vqn">&nbsp;</div>
</div>
</div>
</div>
<div class="content-y8qlFa code-content light-scrollbar-FFk5j5">
<pre class="container-S2LAkl language-bash"><code># 查看项目服务日志（Python/Java）
sudo journalctl -u your-project -f # -f实时跟踪
# 查看Nginx日志
sudo tail -f /var/log/nginx/access.log # 访问日志
sudo tail -f /var/log/nginx/error.log # 错误日志
</code></pre>
</div>
<div class="mask-wrapper-ujeSdZ">
<div class="mask-lrkkzM">&nbsp;</div>
</div>
</div>
</div>
<h4 class="header-iWP5WJ auto-hide-last-sibling-br">2. 项目更新（迭代部署）</h4>
<div class="code-block-element-R6c8c0 light custom-code-block-container--bash hide-indicator disable-theme-style custom-code-block-container">
<div class="code-area-yxsM36 code-area" dir="ltr">
<div class="header-wrapper-Mbk8s6">
<div class="header-IAeXdE">
<div class="title-TXcgFG clickable-cKrA4B" tabindex="0" aria-describedby="9t89ofk" data-popupid="9t89ofk">
<div class="text-OkYU_0">bash</div>
<div class="icon-UKNQeW">&nbsp;</div>
</div>
<div class="action-ysQCxz">
<div class="hoverable-kRHiX2">运行</div>
<div class="hoverable-kRHiX2" tabindex="0" data-testid="code-block-copy" aria-describedby="iwex7qe" data-popupid="iwex7qe">&nbsp;</div>
<div class="hoverable-kRHiX2" tabindex="0" aria-describedby="l6t7rrc" data-popupid="l6t7rrc">&nbsp;</div>
<div class="hoverable-kRHiX2" tabindex="0" aria-describedby="rumm089" data-popupid="rumm089">&nbsp;</div>
<div class="hoverable-kRHiX2" tabindex="0" data-testid="code-block-preview" aria-describedby="lwdnog0" data-popupid="lwdnog0">&nbsp;</div>
</div>
</div>
</div>
<div class="content-y8qlFa code-content light-scrollbar-FFk5j5">
<pre class="container-S2LAkl language-bash"><code># 1. 拉取最新代码
cd /var/www/your-project
git pull
# 2. 重新构建/安装依赖（按需）
# 前端：npm install &amp;&amp; npm run build
# Python：source venv/bin/activate &amp;&amp; pip install -r requirements.txt
# Java：替换新的Jar包
# 3. 重启服务
sudo systemctl restart your-project
# 4. 重启Nginx（若配置有变更）
sudo systemctl restart nginx
</code></pre>
</div>
<div class="mask-wrapper-ujeSdZ">
<div class="mask-lrkkzM">&nbsp;</div>
</div>
</div>
</div>
<h4 class="header-iWP5WJ auto-hide-last-sibling-br">3. 防火墙配置（安全）</h4>
<div class="auto-hide-last-sibling-br paragraph-pP9ZLC paragraph-element br-paragraph-space">Ubuntu 默认用&nbsp;<code>ufw</code>&nbsp;防火墙，仅开放必要端口（80/443/22）：</div>
<div class="container-Uxvbjy md-box-line-break wrapper-GYqxgQ undefined">&nbsp;</div>
<div class="code-block-element-R6c8c0 light custom-code-block-container--bash hide-indicator disable-theme-style custom-code-block-container">
<div class="code-area-yxsM36 code-area" dir="ltr">
<div class="header-wrapper-Mbk8s6">
<div class="header-IAeXdE">
<div class="title-TXcgFG clickable-cKrA4B" tabindex="0" aria-describedby="bzd9y65" data-popupid="bzd9y65">
<div class="text-OkYU_0">bash</div>
<div class="icon-UKNQeW">&nbsp;</div>
</div>
<div class="action-ysQCxz">
<div class="hoverable-kRHiX2">运行</div>
<div class="hoverable-kRHiX2" tabindex="0" data-testid="code-block-copy" aria-describedby="xm3b4ec" data-popupid="xm3b4ec">&nbsp;</div>
<div class="hoverable-kRHiX2" tabindex="0" aria-describedby="blge3gm" data-popupid="blge3gm">&nbsp;</div>
<div class="hoverable-kRHiX2" tabindex="0" aria-describedby="x5cak8h" data-popupid="x5cak8h">&nbsp;</div>
<div class="hoverable-kRHiX2" tabindex="0" data-testid="code-block-preview" aria-describedby="0nmp41j" data-popupid="0nmp41j">&nbsp;</div>
</div>
</div>
</div>
<div class="content-y8qlFa code-content light-scrollbar-FFk5j5">
<pre class="container-S2LAkl language-bash"><code># 启用防火墙
sudo ufw enable
# 允许SSH（22端口）
sudo ufw allow 22
# 允许HTTP（80端口）
sudo ufw allow 80
# 允许HTTPS（443端口，若配置SSL）
sudo ufw allow 443
# 查看防火墙状态
sudo ufw status
</code></pre>
</div>
<div class="mask-wrapper-ujeSdZ">
<div class="mask-lrkkzM">&nbsp;</div>
</div>
</div>
</div>
<h4 class="header-iWP5WJ auto-hide-last-sibling-br">4. 配置 HTTPS（可选，推荐）</h4>
<div class="auto-hide-last-sibling-br paragraph-pP9ZLC paragraph-element br-paragraph-space">用 Let's Encrypt 免费证书配置 HTTPS：</div>
<div class="container-Uxvbjy md-box-line-break wrapper-GYqxgQ undefined">&nbsp;</div>
<div class="code-block-element-R6c8c0 light custom-code-block-container--bash hide-indicator disable-theme-style custom-code-block-container">
<div class="code-area-yxsM36 code-area" dir="ltr">
<div class="header-wrapper-Mbk8s6">
<div class="header-IAeXdE">
<div class="title-TXcgFG clickable-cKrA4B" tabindex="0" aria-describedby="a26k911" data-popupid="a26k911">
<div class="text-OkYU_0">bash</div>
<div class="icon-UKNQeW">&nbsp;</div>
</div>
<div class="action-ysQCxz">
<div class="hoverable-kRHiX2">运行</div>
<div class="hoverable-kRHiX2" tabindex="0" data-testid="code-block-copy" aria-describedby="9u3nhzt" data-popupid="9u3nhzt">&nbsp;</div>
<div class="hoverable-kRHiX2" tabindex="0" aria-describedby="htapkij" data-popupid="htapkij">&nbsp;</div>
<div class="hoverable-kRHiX2" tabindex="0" aria-describedby="xw998ca" data-popupid="xw998ca">&nbsp;</div>
<div class="hoverable-kRHiX2" tabindex="0" data-testid="code-block-preview" aria-describedby="5gg04k2" data-popupid="5gg04k2">&nbsp;</div>
</div>
</div>
</div>
<div class="content-y8qlFa code-content light-scrollbar-FFk5j5">
<pre class="container-S2LAkl language-bash"><code># 安装Certbot
sudo apt install -y certbot python3-certbot-nginx
# 申请并配置证书（自动修改Nginx配置）
sudo certbot --nginx -d your-domain.com
# 设置证书自动续期
sudo certbot renew --dry-run
</code></pre>
</div>
<div class="mask-wrapper-ujeSdZ">
<div class="mask-lrkkzM">&nbsp;</div>
</div>
</div>
</div>
<h3 class="header-iWP5WJ auto-hide-last-sibling-br">四、常见问题排查</h3>
<ol class="auto-hide-last-sibling-br">
<li><strong>项目无法访问</strong>：
<ul class="auto-hide-last-sibling-br">
<li>检查防火墙是否开放端口；</li>
<li>检查服务是否运行（<code>systemctl status your-project</code>）；</li>
<li>检查 Nginx 配置（<code>nginx -t</code>）和日志。</li>
</ul>
</li>
<li><strong>依赖安装失败</strong>：
<ul class="auto-hide-last-sibling-br">
<li>Python：确保虚拟环境激活，换国内源（<code>pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple</code>）；</li>
<li>Node.js：换国内源（<code>npm config set registry https://registry.npmmirror.com</code>）。</li>
</ul>
</li>
<li><strong>进程崩溃</strong>：
<ul class="auto-hide-last-sibling-br">
<li>查看日志（<code>journalctl -u your-project</code>）；</li>
<li>检查内存 / CPU 是否不足（<code>top/htop</code>）。</li>
</ul>
</li>
</ol>
<div class="container-Uxvbjy md-box-line-break wrapper-GYqxgQ undefined">&nbsp;</div>
<div class="auto-hide-last-sibling-br paragraph-pP9ZLC paragraph-element br-paragraph-space">以上是 Ubuntu 部署项目的核心流程，不同项目（如 Node.js、PHP）的部署逻辑类似，核心是「环境 + 服务运行 + 反向代理」。若需具体项目（如 Node.js、PHP）的部署细节，可进一步说明。<button class="semi-button semi-button-primary samantha-button-BghSMg tertiary-o1h39p small-e8_KcA icon-hKywyK icon-only-BL0gii action-btn-rRZksY button-ayOaHN semi-button-with-icon semi-button-with-icon-only" tabindex="0" type="button" data-testid="audio_play_button" aria-disabled="false" aria-describedby="yreutxz" data-popupid="yreutxz"></button></div>
</div>
</div>
</div>
</div>
<div class="flex-row flex max-w-full min-w-0 flex-grow">
<div class="flex flex-col justify-end h-40 w-full select-none opacity-100" data-testid="message_action_bar">
<div class="message-action-bar-raqbg0 flex flex-row w-full group">&nbsp;</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="top-FLPRDF">
<div class="container-SrVXPg chrome70-container">&nbsp;</div>
</div>]]></description>
    <pubDate>Fri, 19 Dec 2025 14:08:37 +0800</pubDate>
    <dc:creator>8vznTUnG</dc:creator>
    <guid>https://top.zhongtongzttb.com.cn/?post=79</guid>
</item>
<item>
    <title>Ubuntu系统常用命令</title>
    <link>https://top.zhongtongzttb.com.cn/?post=78</link>
    <description><![CDATA[<div class="inter-H_fm37">
<div class="container-PvPoAn">
<div class="item-kDun2N">
<div class="container-SrVXPg chrome70-container">
<div class="inner-Qo5lJS inner-item-w21SQO" data-target-id="message-box-target-id" data-testid="union_message">
<div class="message-block-container-PggqdK" data-testid="message-block-container" data-ui-version="samantha">
<div class="flex flex-row w-full w-full max-w-full s-font-base text-s-color-text-secondary p-0 rounded-s-radius-s bg-transparent group data-[attr=select-mode]:-mt-10 data-[attr=select-mode]:py-10 data-[attr=select-mode]:px-16 data-[attr=select-mode]:sm:p-10 data-[attr=select-mode]:hover:bg-s-color-bg-base data-[attr=select-mode]:hover:rounded-s-radius-xs data-[attr=select-mode]:has-[:checked]:bg-s-color-bg-trans data-[attr=select-mode]:has-[:checked]:rounded-s-radius-xs data-[attr=select-mode]:pointer-events-none" data-testid="receive_message" data-copy-telemetry="right_click_copy">
<div class="flex flex-col flex-grow max-w-full min-w-0">
<div class="flex-row flex w-full" data-testid="message_content" data-message-id="33685367757310210">
<div class="flex w-full flex-col [&amp;&gt;div:not(:last-child):not(:empty)]:mb-20" style="outline: none; -webkit-font-smoothing: antialiased; box-sizing: border-box; -webkit-tap-highlight-color: rgba(0, 0, 0, 0); border: 0px solid; margin: 0px; padding: 0px; --desktop-home-page-background-color: #f4f4f4; --desktop-home-card-background-color: #fdfdfd; --desktop-home-card-background-color-hover: #fff; --desktop-home-popup-background-color: #f6f5f5; display: flex; width: 793px; flex-direction: column; overflow-anchor: auto;">
<div class="" data-render-engine="node" data-plugin-identifier="block_type:10000">
<div class="container-P2rR72 flow-markdown-body mdbox-theme-next theme-samantha-uDexJL" dir="ltr" data-testid="message_text_content" data-show-indicator="false">
<div class="auto-hide-last-sibling-br paragraph-pP9ZLC paragraph-element br-paragraph-space">Ubuntu 作为主流的 Linux 发行版，其命令行操作是高效管理系统的核心。以下按<strong>基础操作、文件管理、系统管理、软件管理、网络操作、权限管理</strong>&nbsp;六大类整理常用命令，兼顾新手和进阶场景：</div>
<h3 class="header-iWP5WJ auto-hide-last-sibling-br">一、基础操作（终端通用）</h3>
<div class="auto-hide-last-sibling-br mdbox-table-root table-container-cYf_5N" data-scroll-inline-overflow="false" data-scroll-inline-at-start="true" data-scroll-inline-start-overflow="false" data-scroll-inline-at-end="true" data-scroll-inline-end-overflow="false">
<div class="table-scroll-container-Gyf4hQ mdbox-table-scroll-container">
<table>
<thead>
<tr>
<th>命令</th>
<th>作用</th>
<th>示例</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>ls</code></td>
<td>列出目录内容</td>
<td><code>ls -l</code>（详细列表）、<code>ls -a</code>（显示隐藏文件）、<code>ls -lh</code>（人性化大小）</td>
</tr>
<tr>
<td><code>cd</code></td>
<td>切换目录</td>
<td><code>cd /home</code>（绝对路径）、<code>cd ..</code>（上级目录）、<code>cd ~</code>（用户家目录）、<code>cd -</code>（返回上一次目录）</td>
</tr>
<tr>
<td><code>pwd</code></td>
<td>显示当前工作目录</td>
<td><code>pwd</code></td>
</tr>
<tr>
<td><code>clear</code></td>
<td>清空终端屏幕</td>
<td><code>clear</code>（快捷键&nbsp;<code>Ctrl+L</code>&nbsp;等效）</td>
</tr>
<tr>
<td><code>history</code></td>
<td>查看历史命令</td>
<td><code>history</code>（显示所有）、<code>history 10</code>（最近 10 条）、<code>!5</code>（执行第 5 条历史命令）</td>
</tr>
<tr>
<td><code>exit</code></td>
<td>退出终端 / SSH 连接</td>
<td><code>exit</code></td>
</tr>
<tr>
<td><code>man</code></td>
<td>查看命令手册（帮助）</td>
<td><code>man ls</code>（查看 ls 命令说明）、<code>man -k 关键词</code>（搜索相关命令）</td>
</tr>
<tr>
<td><code>echo</code></td>
<td>输出文本 / 变量</td>
<td><code>echo "hello"</code>、<code>echo $PATH</code>（显示环境变量）</td>
</tr>
</tbody>
</table>
</div>
</div>
<h3 class="header-iWP5WJ auto-hide-last-sibling-br">二、文件 / 目录管理</h3>
<div class="auto-hide-last-sibling-br mdbox-table-root table-container-cYf_5N" data-scroll-inline-overflow="false" data-scroll-inline-at-start="true" data-scroll-inline-start-overflow="false" data-scroll-inline-at-end="true" data-scroll-inline-end-overflow="false">
<div class="table-scroll-container-Gyf4hQ mdbox-table-scroll-container">
<table>
<thead>
<tr>
<th>命令</th>
<th>作用</th>
<th>示例</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>mkdir</code></td>
<td>创建目录</td>
<td><code>mkdir test</code>（单目录）、<code>mkdir -p a/b/c</code>（递归创建多级目录）</td>
</tr>
<tr>
<td><code>rm</code></td>
<td>删除文件 / 目录</td>
<td><code>rm file.txt</code>（删文件）、<code>rm -r dir</code>（删目录）、<code>rm -rf dir</code>（强制删除，慎用！）</td>
</tr>
<tr>
<td><code>cp</code></td>
<td>复制文件 / 目录</td>
<td><code>cp file.txt /tmp/</code>（复制文件）、<code>cp -r dir /tmp/</code>（复制目录）</td>
</tr>
<tr>
<td><code>mv</code></td>
<td>移动 / 重命名</td>
<td><code>mv file.txt /tmp/</code>（移动）、<code>mv old.txt new.txt</code>（重命名）</td>
</tr>
<tr>
<td><code>touch</code></td>
<td>创建空文件 / 更新时间戳</td>
<td><code>touch new.txt</code></td>
</tr>
<tr>
<td><code>cat</code></td>
<td>查看文件内容（短文件）</td>
<td><code>cat /etc/hosts</code>、<code>cat file1 file2 &gt; file3</code>（合并文件）</td>
</tr>
<tr>
<td><code>more/less</code></td>
<td>分页查看长文件</td>
<td><code>less /var/log/syslog</code>（按空格翻页，q 退出，支持搜索）</td>
</tr>
<tr>
<td><code>head/tail</code></td>
<td>查看文件开头 / 结尾</td>
<td><code>head -10 /etc/passwd</code>（前 10 行）、<code>tail -f /var/log/syslog</code>（实时跟踪日志）</td>
</tr>
<tr>
<td><code>find</code></td>
<td>查找文件 / 目录</td>
<td><code>find /home -name "*.txt"</code>（按名称找）、<code>find / -size +100M</code>（找大于 100M 的文件）</td>
</tr>
<tr>
<td><code>grep</code></td>
<td>文本搜索（过滤）</td>
<td><code>grep "error" /var/log/syslog</code>（找包含 error 的行）、<code>grep -i "Error" file</code>（忽略大小写）、<code>grep -r "test" /etc/</code>（递归搜索目录）</td>
</tr>
<tr>
<td><code>chmod</code></td>
<td>修改文件权限</td>
<td><code>chmod 755 script.sh</code>（rwxr-xr-x）、<code>chmod +x script.sh</code>（添加执行权限）</td>
</tr>
<tr>
<td><code>chown</code></td>
<td>修改文件所属主 / 组</td>
<td><code>chown user:group file.txt</code>（改用户和组）、<code>chown -R user:group dir/</code>（递归改目录）</td>
</tr>
</tbody>
</table>
</div>
</div>
<h3 class="header-iWP5WJ auto-hide-last-sibling-br">三、系统管理</h3>
<div class="auto-hide-last-sibling-br mdbox-table-root table-container-cYf_5N" data-scroll-inline-overflow="true" data-scroll-inline-at-start="true" data-scroll-inline-start-overflow="false" data-scroll-inline-at-end="false" data-scroll-inline-end-overflow="true">
<div class="table-scroll-container-Gyf4hQ mdbox-table-scroll-container">
<table>
<thead>
<tr>
<th>命令</th>
<th>作用</th>
<th>示例</th>
<th>&nbsp;</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>sudo</code></td>
<td>以管理员权限执行命令</td>
<td><code>sudo apt update</code>、<code>sudo -i</code>（切换到 root 用户）</td>
<td>&nbsp;</td>
</tr>
<tr>
<td><code>su</code></td>
<td>切换用户</td>
<td><code>su root</code>（切 root）、<code>su - user</code>（切换并加载用户环境）</td>
<td>&nbsp;</td>
</tr>
<tr>
<td><code>top</code></td>
<td>实时监控系统进程（类似 Windows 任务管理器）</td>
<td><code>top</code>（按 q 退出，按 P 按 CPU 排序，按 M 按内存排序）</td>
<td>&nbsp;</td>
</tr>
<tr>
<td><code>htop</code></td>
<td>增强版 top（需安装：<code>sudo apt install htop</code>）</td>
<td><code>htop</code></td>
<td>&nbsp;</td>
</tr>
<tr>
<td><code>ps</code></td>
<td>查看进程</td>
<td><code>ps aux</code>（所有进程）、`ps aux</td>
<td>grep nginx`（过滤 nginx 进程）</td>
</tr>
<tr>
<td><code>kill</code></td>
<td>终止进程</td>
<td><code>kill 1234</code>（按 PID 终止）、<code>kill -9 1234</code>（强制终止，慎用）</td>
<td>&nbsp;</td>
</tr>
<tr>
<td><code>df</code></td>
<td>查看磁盘空间</td>
<td><code>df -h</code>（人性化显示磁盘使用情况）</td>
<td>&nbsp;</td>
</tr>
<tr>
<td><code>du</code></td>
<td>查看文件 / 目录大小</td>
<td><code>du -sh /home</code>（显示 /home 总大小）、<code>du -h /var/log</code>（列出目录下文件大小）</td>
<td>&nbsp;</td>
</tr>
<tr>
<td><code>free</code></td>
<td>查看内存 / 交换分区</td>
<td><code>free -h</code>（人性化显示）</td>
<td>&nbsp;</td>
</tr>
<tr>
<td><code>uname</code></td>
<td>查看系统信息</td>
<td><code>uname -a</code>（所有信息）、<code>uname -r</code>（内核版本）</td>
<td>&nbsp;</td>
</tr>
<tr>
<td><code>hostname</code></td>
<td>查看 / 修改主机名</td>
<td><code>hostname</code>（查看）、<code>sudo hostname new-name</code>（临时修改）</td>
<td>&nbsp;</td>
</tr>
<tr>
<td><code>reboot/shutdown</code></td>
<td>重启 / 关机</td>
<td><code>sudo reboot</code>（重启）、<code>sudo shutdown -h now</code>（立即关机）、<code>sudo shutdown -h 20:00</code>（定时关机）</td>
<td>&nbsp;</td>
</tr>
</tbody>
</table>
</div>
</div>
<h3 class="header-iWP5WJ auto-hide-last-sibling-br">四、软件包管理（APT，Ubuntu 默认）</h3>
<div class="auto-hide-last-sibling-br mdbox-table-root table-container-cYf_5N" data-scroll-inline-overflow="true" data-scroll-inline-at-start="true" data-scroll-inline-start-overflow="false" data-scroll-inline-at-end="false" data-scroll-inline-end-overflow="true">
<div class="table-scroll-container-Gyf4hQ mdbox-table-scroll-container">
<table>
<thead>
<tr>
<th>命令</th>
<th>作用</th>
<th>示例</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>apt update</code></td>
<td>更新软件源索引（必先执行）</td>
<td><code>sudo apt update</code></td>
</tr>
<tr>
<td><code>apt upgrade</code></td>
<td>升级所有已安装软件</td>
<td><code>sudo apt upgrade</code>（按 Y 确认）</td>
</tr>
<tr>
<td><code>apt install</code></td>
<td>安装软件</td>
<td><code>sudo apt install nginx</code>、<code>sudo apt install -y nginx</code>（自动确认）</td>
</tr>
<tr>
<td><code>apt remove</code></td>
<td>卸载软件（保留配置）</td>
<td><code>sudo apt remove nginx</code></td>
</tr>
<tr>
<td><code>apt purge</code></td>
<td>彻底卸载（删除配置）</td>
<td><code>sudo apt purge nginx</code></td>
</tr>
<tr>
<td><code>apt autoremove</code></td>
<td>清理无用依赖</td>
<td><code>sudo apt autoremove</code>（升级 / 卸载后推荐执行）</td>
</tr>
<tr>
<td><code>apt search</code></td>
<td>搜索软件包</td>
<td><code>apt search python3</code></td>
</tr>
<tr>
<td><code>apt show</code></td>
<td>查看软件包信息</td>
<td><code>apt show nginx</code></td>
</tr>
</tbody>
</table>
</div>
</div>
<h3 class="header-iWP5WJ auto-hide-last-sibling-br">五、网络操作</h3>
<div class="auto-hide-last-sibling-br mdbox-table-root table-container-cYf_5N" data-scroll-inline-overflow="true" data-scroll-inline-at-start="true" data-scroll-inline-start-overflow="false" data-scroll-inline-at-end="false" data-scroll-inline-end-overflow="true">
<div class="table-scroll-container-Gyf4hQ mdbox-table-scroll-container">
<table>
<thead>
<tr>
<th>命令</th>
<th>作用</th>
<th>示例</th>
<th>&nbsp;</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>ifconfig</code></td>
<td>查看 / 配置网络接口（需安装 net-tools：<code>sudo apt install net-tools</code>）</td>
<td><code>ifconfig</code>（查看所有网卡）</td>
<td>&nbsp;</td>
</tr>
<tr>
<td><code>ip</code></td>
<td>新一代网络配置命令（替代 ifconfig）</td>
<td><code>ip addr</code>（查看 IP）、<code>ip route</code>（查看路由）</td>
<td>&nbsp;</td>
</tr>
<tr>
<td><code>ping</code></td>
<td>测试网络连通性</td>
<td><code>ping baidu.com</code>（按 Ctrl+C 停止）、<code>ping -c 4 baidu.com</code>（发送 4 个包）</td>
<td>&nbsp;</td>
</tr>
<tr>
<td><code>curl/wget</code></td>
<td>下载文件 / 测试接口</td>
<td><code>curl https://baidu.com</code>（访问网页）、<code>wget https://xxx.com/file.tar.gz</code>（下载文件）</td>
<td>&nbsp;</td>
</tr>
<tr>
<td><code>ss/netstat</code></td>
<td>查看端口占用</td>
<td><code>ss -tuln</code>（查看监听端口）、`netstat -tulnp</td>
<td>grep 80`（查看 80 端口占用进程，需 net-tools）</td>
</tr>
<tr>
<td><code>ssh</code></td>
<td>远程登录服务器</td>
<td><code>ssh user@192.168.1.100</code>、<code>ssh -p 2222 user@ip</code>（指定端口）</td>
<td>&nbsp;</td>
</tr>
</tbody>
</table>
</div>
</div>
<h3 class="header-iWP5WJ auto-hide-last-sibling-br">六、实用技巧 &amp; 注意事项</h3>
<ol class="auto-hide-last-sibling-br">
<li><strong>快捷键</strong>：
<ul class="auto-hide-last-sibling-br">
<li><code>Ctrl+C</code>：终止当前命令执行；</li>
<li><code>Ctrl+D</code>：等效 exit，关闭终端；</li>
<li><code>Tab</code>：自动补全命令 / 文件名（按两次显示所有候选）；</li>
<li><code>Ctrl+R</code>：搜索历史命令（输入关键词匹配）。</li>
</ul>
</li>
<li><strong>通配符</strong>：
<ul class="auto-hide-last-sibling-br">
<li><code>*</code>：匹配任意字符（如<code>ls *.txt</code>）；</li>
<li><code>?</code>：匹配单个字符（如<code>ls file?.txt</code>）。</li>
</ul>
</li>
<li><strong>管道符&nbsp;<code>|</code></strong>：将前一个命令的输出作为后一个命令的输入，如<code>ps aux | grep nginx</code>。</li>
<li><strong>重定向</strong>：
<ul class="auto-hide-last-sibling-br">
<li><code>&gt;</code>：覆盖写入文件（如<code>echo "test" &gt; file.txt</code>）；</li>
<li><code>&gt;&gt;</code>：追加写入文件（如<code>echo "test" &gt;&gt; file.txt</code>）。</li>
</ul>
</li>
</ol>
<div class="container-Uxvbjy md-box-line-break wrapper-GYqxgQ undefined">&nbsp;</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="top-FLPRDF">
<div class="container-SrVXPg chrome70-container">&nbsp;</div>
</div>]]></description>
    <pubDate>Fri, 19 Dec 2025 11:46:20 +0800</pubDate>
    <dc:creator>8vznTUnG</dc:creator>
    <guid>https://top.zhongtongzttb.com.cn/?post=78</guid>
</item>
<item>
    <title>怎么设计一个软件的数据库模型</title>
    <link>https://top.zhongtongzttb.com.cn/?post=77</link>
    <description><![CDATA[<div class="auto-hide-last-sibling-br paragraph-JOTKXA paragraph-element br-paragraph-space">设计软件的数据库模型是将业务需求转化为结构化数据存储方案的核心过程，需要兼顾业务逻辑、数据完整性、查询效率和可扩展性。以下是一套系统化的设计流程和实践方法，附具体案例说明：</div>
<h3 class="header-vfC6AV auto-hide-last-sibling-br">一、前提：明确业务需求（避免 &ldquo;为设计而设计&rdquo;）</h3>
<div class="auto-hide-last-sibling-br paragraph-JOTKXA paragraph-element br-paragraph-space">数据库模型的本质是<strong>业务的数字化映射</strong>，设计前必须彻底厘清需求：</div>
<div class="container-utlnW2 md-box-line-break wrapper-d0Cc1k undefined">&nbsp;</div>
<ol class="auto-hide-last-sibling-br">
<li>
<div class="auto-hide-last-sibling-br paragraph-JOTKXA paragraph-element br-paragraph-space"><strong>梳理核心业务流程</strong>：
<div class="container-utlnW2 md-box-line-break wrapper-d0Cc1k undefined">&nbsp;</div>
用流程图或文字描述软件的关键操作（如电商的 &ldquo;下单&rarr;支付&rarr;发货&rdquo;，社交的 &ldquo;注册&rarr;发动态&rarr;评论&rdquo;），明确每个流程涉及的数据输入、处理和输出。
<div class="container-utlnW2 md-box-line-break wrapper-d0Cc1k undefined">&nbsp;</div>
例：外卖系统核心流程：用户下单&rarr;商家接单&rarr;骑手取餐&rarr;用户确认收货。</div>
</li>
<li>
<div class="auto-hide-last-sibling-br paragraph-JOTKXA paragraph-element br-paragraph-space"><strong>提取实体与属性</strong>：
<div class="container-utlnW2 md-box-line-break wrapper-d0Cc1k undefined">&nbsp;</div>
从流程中识别核心 &ldquo;实体&rdquo;（业务对象），并列出每个实体的 &ldquo;属性&rdquo;（特征）：</div>
<ul class="auto-hide-last-sibling-br">
<li>实体：可理解为 &ldquo;名词&rdquo;（用户、订单、商品、骑手等）；</li>
<li>属性：实体的描述信息（用户有手机号、姓名；订单有金额、创建时间等）。
<div class="container-utlnW2 md-box-line-break wrapper-d0Cc1k undefined">&nbsp;</div>
例：外卖系统实体清单：<code>User</code>（用户）、<code>Merchant</code>（商家）、<code>Order</code>（订单）、<code>Food</code>（食品）、<code>Rider</code>（骑手）。</li>
</ul>
</li>
<li>
<div class="auto-hide-last-sibling-br paragraph-JOTKXA paragraph-element br-paragraph-space"><strong>明确实体关系</strong>：
<div class="container-utlnW2 md-box-line-break wrapper-d0Cc1k undefined">&nbsp;</div>
确定实体间的关联方式（一对一、一对多、多对多）：</div>
<ul class="auto-hide-last-sibling-br">
<li>例：<code>User</code>与<code>Order</code>是 &ldquo;一对多&rdquo;（一个用户可下多个订单）；</li>
<li><code>Order</code>与<code>Food</code>是 &ldquo;多对多&rdquo;（一个订单含多种食品，一种食品可在多个订单中）。</li>
</ul>
</li>
</ol>
<h3 class="header-vfC6AV auto-hide-last-sibling-br">二、步骤 1：概念模型设计（画 ER 图，无关具体数据库）</h3>
<div class="auto-hide-last-sibling-br paragraph-JOTKXA paragraph-element br-paragraph-space">概念模型是业务的 &ldquo;抽象蓝图&rdquo;，用<strong>ER 图（实体 - 关系图）</strong>&nbsp;表示，不涉及数据库类型（如 MySQL、PostgreSQL），只关注 &ldquo;实体、属性、关系&rdquo;。</div>
<h4 class="header-vfC6AV auto-hide-last-sibling-br">核心要素：</h4>
<ul class="auto-hide-last-sibling-br">
<li><strong>实体（Entity）</strong>：用矩形表示，标注实体名称（如<code>User</code>、<code>Order</code>）。</li>
<li><strong>属性（Attribute）</strong>：用椭圆表示，与实体连接（如<code>User</code>的<code>id</code>、<code>phone</code>、<code>name</code>）。</li>
<li><strong>主键（Primary Key）</strong>：属性中能唯一标识实体的字段（如<code>User.id</code>），下划线标注。</li>
<li><strong>关系（Relationship）</strong>：用菱形表示，标注关系类型（如 &ldquo;下单&rdquo;&ldquo;包含&rdquo;），并注明 cardinality（1:1、1:N、M:N）。</li>
</ul>
<h4 class="header-vfC6AV auto-hide-last-sibling-br">案例：外卖系统简化 ER 图</h4>
<div class="code-block-element-YDlfvc light custom-code-block-container--plaintext hide-indicator disable-theme-style custom-code-block-container">
<div class="code-area-tZtDgG code-area" dir="ltr">
<div class="header-wrapper-UnnlXS">
<div class="header-cGu84a">
<div class="title-XQhI4x clickable-eGISjP" tabindex="0" aria-describedby="mv05d9r" data-popupid="mv05d9r">
<div class="text-jgT4jF">plaintext</div>
<div class="icon-FIfuuc">&nbsp;</div>
</div>
<div class="action-tEcs3i">
<div class="hoverable-sPLxOT" tabindex="0" data-testid="code-block-copy" aria-describedby="w0pgfni" data-popupid="w0pgfni">&nbsp;</div>
<div class="hoverable-sPLxOT" tabindex="0" aria-describedby="mokjlcl" data-popupid="mokjlcl">&nbsp;</div>
<div class="hoverable-sPLxOT" tabindex="0" aria-describedby="3qs6jgd" data-popupid="3qs6jgd">&nbsp;</div>
<div class="hoverable-sPLxOT" tabindex="0" aria-describedby="dlnn5la" data-popupid="dlnn5la">&nbsp;</div>
</div>
</div>
</div>
<div class="content-EGRozu code-content light-scrollbar-TbsSwi">
<pre class="container-_HmLba language-plaintext"><code>+--------+       1    +--------+       N    +--------+  
|  User  |&lt;----------&gt;|  Order |&lt;----------&gt;|  Food  |  
+--------+    下单    +--------+    包含    +--------+  
  | id        (1:N)     | id          (M:N)   | id  
  | phone               | amount            | name  
  | name                | status            | price  
                        | create_time       | merchant_id  
                                          +--------+  
+--------+       1     |  OrderFood  |     |Merchant|  
|Rider   |&lt;-----------&gt;| (中间表)    |     +--------+  
+--------+    配送     | order_id    |       | id  
  | id          (1:1)  | food_id     |       | name  
  | name               | quantity    |       | address  
  | phone              +-------------+       | status  
</code></pre>
</div>
<div class="mask-wrapper-VgpgeU">
<div class="mask-ZLHDuN">&nbsp;</div>
</div>
</div>
</div>
<h3 class="header-vfC6AV auto-hide-last-sibling-br">三、步骤 2：逻辑模型设计（转化为表结构，数据库无关）</h3>
<div class="auto-hide-last-sibling-br paragraph-JOTKXA paragraph-element br-paragraph-space">将 ER 图转化为<strong>关系模型</strong>（表结构），明确每张表的字段、数据类型、约束，不涉及具体数据库的特性（如索引类型、存储引擎）。</div>
<h4 class="header-vfC6AV auto-hide-last-sibling-br">关键操作：</h4>
<ol class="auto-hide-last-sibling-br">
<li>
<div class="auto-hide-last-sibling-br paragraph-JOTKXA paragraph-element br-paragraph-space"><strong>实体&rarr;表</strong>：每个实体对应一张表，实体名称即为表名（如<code>User</code>实体&rarr;<code>user</code>表）。</div>
</li>
<li>
<div class="auto-hide-last-sibling-br paragraph-JOTKXA paragraph-element br-paragraph-space"><strong>属性&rarr;字段</strong>：</div>
<ul class="auto-hide-last-sibling-br">
<li>为每个字段指定<strong>数据类型</strong>（遵循 &ldquo;最小够用&rdquo; 原则，如手机号用<code>CHAR(11)</code>而非<code>VARCHAR(20)</code>）；</li>
<li>标记<strong>约束</strong>：<code>NOT NULL</code>（必填）、<code>UNIQUE</code>（唯一）、<code>DEFAULT</code>（默认值）等。</li>
</ul>
</li>
<li>
<div class="auto-hide-last-sibling-br paragraph-JOTKXA paragraph-element br-paragraph-space"><strong>关系&rarr;表 / 字段</strong>：</div>
<ul class="auto-hide-last-sibling-br">
<li><strong>1:1 关系</strong>：在其中一张表中加外键（如<code>User</code>与<code>UserDetail</code>，在<code>user_detail</code>表加<code>user_id</code>外键关联<code>user.id</code>，并设<code>UNIQUE</code>保证唯一）。</li>
<li><strong>1:N 关系</strong>：在 &ldquo;多&rdquo; 的表中加外键（如<code>User</code>(1) 与<code>Order</code>(N)，在<code>order</code>表加<code>user_id</code>外键关联<code>user.id</code>）。</li>
<li><strong>M:N 关系</strong>：新增中间表，存储两个实体的主键（如<code>Order</code>与<code>Food</code>的 M:N 关系，新增<code>order_food</code>表，含<code>order_id</code>和<code>food_id</code>两个外键，联合主键）。</li>
</ul>
</li>
</ol>
<h4 class="header-vfC6AV auto-hide-last-sibling-br">案例：外卖系统逻辑模型（表结构）</h4>
<div class="auto-hide-last-sibling-br mdbox-table-root table-container-GhL7Lo" data-scroll-inline-overflow="false" data-scroll-inline-at-start="true" data-scroll-inline-start-overflow="false" data-scroll-inline-at-end="true" data-scroll-inline-end-overflow="false">
<div class="table-scroll-container-hgHkfW mdbox-table-scroll-container">
<table>
<thead>
<tr>
<th>表名</th>
<th>字段名</th>
<th>数据类型</th>
<th>约束</th>
<th>说明</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>user</code></td>
<td><code>id</code></td>
<td><code>BIGINT</code></td>
<td><code>PK, AUTO_INCREMENT</code></td>
<td>用户唯一标识</td>
</tr>
<tr>
<td>&nbsp;</td>
<td><code>phone</code></td>
<td><code>CHAR(11)</code></td>
<td><code>NOT NULL, UNIQUE</code></td>
<td>手机号（登录账号）</td>
</tr>
<tr>
<td>&nbsp;</td>
<td><code>name</code></td>
<td><code>VARCHAR(50)</code></td>
<td><code>NOT NULL</code></td>
<td>用户名</td>
</tr>
<tr>
<td>&nbsp;</td>
<td><code>create_time</code></td>
<td><code>DATETIME</code></td>
<td><code>NOT NULL, DEFAULT NOW()</code></td>
<td>创建时间</td>
</tr>
<tr>
<td>--------------</td>
<td>-----------------</td>
<td>------------------</td>
<td>-----------------------</td>
<td>-----------------------</td>
</tr>
<tr>
<td><code>order</code></td>
<td><code>id</code></td>
<td><code>BIGINT</code></td>
<td><code>PK, AUTO_INCREMENT</code></td>
<td>订单唯一标识</td>
</tr>
<tr>
<td>&nbsp;</td>
<td><code>user_id</code></td>
<td><code>BIGINT</code></td>
<td><code>NOT NULL, FK&rarr;user.id</code></td>
<td>关联用户</td>
</tr>
<tr>
<td>&nbsp;</td>
<td><code>merchant_id</code></td>
<td><code>BIGINT</code></td>
<td><code>NOT NULL, FK&rarr;merchant.id</code></td>
<td>关联商家</td>
</tr>
<tr>
<td>&nbsp;</td>
<td><code>amount</code></td>
<td><code>DECIMAL(10,2)</code></td>
<td><code>NOT NULL</code></td>
<td>订单总金额</td>
</tr>
<tr>
<td>&nbsp;</td>
<td><code>status</code></td>
<td><code>TINYINT</code></td>
<td><code>NOT NULL, DEFAULT 0</code></td>
<td>状态（0 待支付 / 1 已接单...）</td>
</tr>
<tr>
<td>--------------</td>
<td>-----------------</td>
<td>------------------</td>
<td>-----------------------</td>
<td>-----------------------</td>
</tr>
<tr>
<td><code>order_food</code></td>
<td><code>order_id</code></td>
<td><code>BIGINT</code></td>
<td><code>PK, FK&rarr;order.id</code></td>
<td>关联订单</td>
</tr>
<tr>
<td>&nbsp;</td>
<td><code>food_id</code></td>
<td><code>BIGINT</code></td>
<td><code>PK, FK&rarr;food.id</code></td>
<td>关联食品</td>
</tr>
<tr>
<td>&nbsp;</td>
<td><code>quantity</code></td>
<td><code>INT</code></td>
<td><code>NOT NULL</code></td>
<td>购买数量</td>
</tr>
</tbody>
</table>
</div>
</div>
<h3 class="header-vfC6AV auto-hide-last-sibling-br">四、步骤 3：物理模型设计（适配具体数据库，性能优化）</h3>
<div class="auto-hide-last-sibling-br paragraph-JOTKXA paragraph-element br-paragraph-space">根据所选数据库（如 MySQL、PostgreSQL），将逻辑模型转化为可落地的物理模型，重点关注<strong>存储优化、索引设计、事务支持</strong>等数据库特性。</div>
<h4 class="header-vfC6AV auto-hide-last-sibling-br">关键操作：</h4>
<ol class="auto-hide-last-sibling-br">
<li>
<div class="auto-hide-last-sibling-br paragraph-JOTKXA paragraph-element br-paragraph-space"><strong>选择存储引擎</strong>（以 MySQL 为例）：</div>
<ul class="auto-hide-last-sibling-br">
<li>需事务、外键：选<code>InnoDB</code>（支持 ACID、行级锁）；</li>
<li>读多写少的静态数据（如字典表）：可选<code>MyISAM</code>（查询更快，但不支持事务）。</li>
</ul>
</li>
<li>
<div class="auto-hide-last-sibling-br paragraph-JOTKXA paragraph-element br-paragraph-space"><strong>索引设计</strong>：</div>
<ul class="auto-hide-last-sibling-br">
<li>主键索引：默认由数据库自动创建（如<code>user.id</code>）；</li>
<li>外键索引：所有外键必须建索引（如<code>order.user_id</code>，避免 JOIN 时全表扫描）；</li>
<li>业务索引：高频查询字段（如<code>user.phone</code>（登录查询）、<code>order.status</code>（筛选待处理订单））。</li>
<li>联合索引：多字段查询场景（如<code>WHERE merchant_id=1 AND status=2</code>，建<code>(merchant_id, status)</code>）。</li>
</ul>
</li>
<li>
<div class="auto-hide-last-sibling-br paragraph-JOTKXA paragraph-element br-paragraph-space"><strong>分区 / 分表策略</strong>（针对大数据量）：</div>
<ul class="auto-hide-last-sibling-br">
<li>时间维度：订单表<code>order</code>按<code>create_time</code>分区（如每月一个分区），适合历史数据归档；</li>
<li>范围维度：用户表<code>user</code>按<code>id</code>范围分表（如<code>user_1</code>存<code>id=1~100万</code>，<code>user_2</code>存<code>100万~200万</code>）。</li>
</ul>
</li>
<li>
<div class="auto-hide-last-sibling-br paragraph-JOTKXA paragraph-element br-paragraph-space"><strong>字段优化</strong>：</div>
<ul class="auto-hide-last-sibling-br">
<li>敏感字段加密：手机号、身份证号用加密算法（如 AES）存储，避免明文泄露；</li>
<li>大字段拆分：商品详情等超长文本（<code>TEXT</code>类型）拆分到独立表（如<code>product_detail</code>），避免主表查询效率下降。</li>
</ul>
</li>
</ol>
<h3 class="header-vfC6AV auto-hide-last-sibling-br">五、步骤 4：验证与迭代（用原型和测试发现问题）</h3>
<div class="auto-hide-last-sibling-br paragraph-JOTKXA paragraph-element br-paragraph-space">数据库模型设计不是 &ldquo;一次性工作&rdquo;，需通过验证发现缺陷：</div>
<div class="container-utlnW2 md-box-line-break wrapper-d0Cc1k undefined">&nbsp;</div>
<ol class="auto-hide-last-sibling-br">
<li>
<div class="auto-hide-last-sibling-br paragraph-JOTKXA paragraph-element br-paragraph-space"><strong>原型测试</strong>：
<div class="container-utlnW2 md-box-line-break wrapper-d0Cc1k undefined">&nbsp;</div>
用工具（如 Navicat、PowerDesigner）生成物理模型，创建测试表，插入模拟数据，执行核心业务 SQL（如 &ldquo;查询用户 30 天内的订单&rdquo;&ldquo;统计商家今日销售额&rdquo;），检查是否存在：</div>
<ul class="auto-hide-last-sibling-br">
<li>表关联过多（JOIN 超过 3 张表可能影响性能）；</li>
<li>缺少必要索引（查询耗时过长）；</li>
<li>字段设计不合理（如用<code>VARCHAR</code>存订单状态，无法高效筛选）。</li>
</ul>
</li>
<li>
<div class="auto-hide-last-sibling-br paragraph-JOTKXA paragraph-element br-paragraph-space"><strong>压力测试</strong>：
<div class="container-utlnW2 md-box-line-break wrapper-d0Cc1k undefined">&nbsp;</div>
用工具（如 JMeter）模拟高并发场景（如秒杀时的订单创建），观察：</div>
<ul class="auto-hide-last-sibling-br">
<li>锁冲突（如<code>InnoDB</code>的行锁是否导致插入阻塞）；</li>
<li>索引失效（如大表全表扫描）；</li>
<li>连接数瓶颈（需调整<code>max_connections</code>等参数）。</li>
</ul>
</li>
<li>
<div class="auto-hide-last-sibling-br paragraph-JOTKXA paragraph-element br-paragraph-space"><strong>业务迭代适配</strong>：
<div class="container-utlnW2 md-box-line-break wrapper-d0Cc1k undefined">&nbsp;</div>
当业务新增功能（如外卖系统增加 &ldquo;优惠券&rdquo;），需同步优化模型：</div>
<ul class="auto-hide-last-sibling-br">
<li>新增<code>coupon</code>表（优惠券信息）；</li>
<li>新增<code>order_coupon</code>中间表（订单与优惠券的多对多关系）；</li>
<li>调整<code>order</code>表，增加<code>coupon_discount</code>字段（优惠金额）。</li>
</ul>
</li>
</ol>
<h3 class="header-vfC6AV auto-hide-last-sibling-br">六、工具推荐（提高设计效率）</h3>
<ul class="auto-hide-last-sibling-br">
<li><strong>ER 图工具</strong>：PowerDesigner（功能全）、draw.io（免费）、Navicat（自带 ER 图功能）；</li>
<li><strong>建模工具</strong>：MySQL Workbench（MySQL 官方工具，支持从 ER 图生成 SQL）、dbeaver（跨数据库通用）；</li>
<li><strong>版本管理</strong>：将建表 SQL（<code>CREATE TABLE</code>）纳入 Git 管理，记录模型变更历史。</li>
</ul>
<h3 class="header-vfC6AV auto-hide-last-sibling-br">核心原则总结</h3>
<ol class="auto-hide-last-sibling-br">
<li><strong>业务优先</strong>：模型必须贴合业务，而非强行套用范式；</li>
<li><strong>适度冗余</strong>：为高频查询增加冗余字段（如订单表存<code>merchant_name</code>），减少 JOIN；</li>
<li><strong>可扩展性</strong>：预留扩展字段（如<code>ext_json</code>存动态属性），避免频繁 ALTER TABLE；</li>
<li><strong>性能平衡</strong>：索引不是越多越好（会降低写入速度），需根据查询频率取舍。</li>
</ol>
<div class="container-utlnW2 md-box-line-break wrapper-d0Cc1k undefined">&nbsp;</div>
<div class="auto-hide-last-sibling-br paragraph-JOTKXA paragraph-element br-paragraph-space">通过以上流程，可设计出既满足当前业务需求，又能支撑未来扩展的数据库模型。</div>]]></description>
    <pubDate>Thu, 09 Oct 2025 17:39:46 +0800</pubDate>
    <dc:creator>neal</dc:creator>
    <guid>https://top.zhongtongzttb.com.cn/?post=77</guid>
</item>
<item>
    <title>怎么优化数据库设计</title>
    <link>https://top.zhongtongzttb.com.cn/?post=76</link>
    <description><![CDATA[<div class="auto-hide-last-sibling-br paragraph-JOTKXA paragraph-element br-paragraph-space">优化数据库设计是提升系统性能、保证数据完整性和可扩展性的核心环节，需要结合业务场景、查询模式和数据量等因素综合考量。以下是数据库设计优化的关键方向和具体实践方法：</div>
<h3 class="header-vfC6AV auto-hide-last-sibling-br">一、合理应用范式与反范式，平衡冗余与关联</h3>
<div class="auto-hide-last-sibling-br paragraph-JOTKXA paragraph-element br-paragraph-space">数据库设计的基础是<strong>范式理论</strong>（减少冗余），但过度遵循范式可能导致表关联过多，查询效率下降，因此需根据业务场景灵活调整。</div>
<h4 class="header-vfC6AV auto-hide-last-sibling-br">1. 遵循核心范式（避免数据冗余和异常）</h4>
<ul class="auto-hide-last-sibling-br">
<li><strong>第一范式（1NF）</strong>：确保每个字段不可再分（原子性）。
<div class="container-utlnW2 md-box-line-break wrapper-d0Cc1k undefined">&nbsp;</div>
例：避免在<code>address</code>字段中存储 &ldquo;省 + 市 + 区&rdquo;，应拆分为<code>province</code>、<code>city</code>、<code>district</code>三个独立字段，便于单独查询（如按城市筛选）。</li>
<li><strong>第二范式（2NF）</strong>：在 1NF 基础上，非主键字段必须完全依赖于主键（消除部分依赖）。
<div class="container-utlnW2 md-box-line-break wrapper-d0Cc1k undefined">&nbsp;</div>
例：订单表<code>order</code>中，<code>product_name</code>不应依赖于<code>product_id</code>（部分依赖），而应将商品信息拆分到<code>product</code>表，订单表仅存<code>product_id</code>（外键关联）。</li>
<li><strong>第三范式（3NF）</strong>：在 2NF 基础上，非主键字段不依赖于其他非主键字段（消除传递依赖）。
<div class="container-utlnW2 md-box-line-break wrapper-d0Cc1k undefined">&nbsp;</div>
例：用户表<code>user</code>中，<code>area_name</code>不应依赖于<code>area_id</code>（传递依赖），应将地区信息拆分到<code>area</code>表，用户表仅存<code>area_id</code>。</li>
</ul>
<h4 class="header-vfC6AV auto-hide-last-sibling-br">2. 适当反范式（提升查询效率）</h4>
<div class="auto-hide-last-sibling-br paragraph-JOTKXA paragraph-element br-paragraph-space">当查询频繁涉及多表关联（如报表统计），可<strong>主动增加冗余字段</strong>减少 JOIN 操作：</div>
<div class="container-utlnW2 md-box-line-break wrapper-d0Cc1k undefined">&nbsp;</div>
<ul class="auto-hide-last-sibling-br">
<li>例：电商订单表<code>order</code>中，冗余存储<code>product_name</code>（而非仅存<code>product_id</code>），避免查询订单详情时必须关联<code>product</code>表。</li>
<li>注意：冗余字段需通过触发器、事务或应用层逻辑保证一致性（如商品名称修改时同步更新订单表中的冗余字段）。</li>
</ul>
<h3 class="header-vfC6AV auto-hide-last-sibling-br">二、优化表结构设计，减少存储开销</h3>
<h4 class="header-vfC6AV auto-hide-last-sibling-br">1. 拆分大表（避免 &ldquo;万能表&rdquo;）</h4>
<div class="auto-hide-last-sibling-br paragraph-JOTKXA paragraph-element br-paragraph-space">单表字段过多（如超过 30 个）或数据量过大（如千万级以上）会导致查询和更新效率下降，需按业务维度拆分：</div>
<div class="container-utlnW2 md-box-line-break wrapper-d0Cc1k undefined">&nbsp;</div>
<ul class="auto-hide-last-sibling-br">
<li><strong>垂直拆分</strong>：将大表按字段关联性拆分为多个小表（适合字段多但访问频率差异大的场景）。
<div class="container-utlnW2 md-box-line-break wrapper-d0Cc1k undefined">&nbsp;</div>
例：用户表<code>user</code>拆分为<code>user_base</code>（存储常用字段：id、name、phone）和<code>user_detail</code>（存储不常用字段：birthday、address、avatar），查询登录信息时只需访问<code>user_base</code>。</li>
<li><strong>水平拆分</strong>：将大表按行拆分（适合数据量极大的场景），拆分维度通常为时间、地区、用户 ID 等。
<div class="container-utlnW2 md-box-line-break wrapper-d0Cc1k undefined">&nbsp;</div>
例：日志表<code>log</code>按月份拆分为<code>log_202301</code>、<code>log_202302</code>，查询 2023 年 1 月日志时仅需访问对应分表。</li>
</ul>
<h4 class="header-vfC6AV auto-hide-last-sibling-br">2. 选择合适的数据类型（节省空间 + 提升效率）</h4>
<div class="auto-hide-last-sibling-br paragraph-JOTKXA paragraph-element br-paragraph-space">数据类型选择直接影响存储占用和查询速度，遵循 &ldquo;最小够用&rdquo; 原则：</div>
<div class="container-utlnW2 md-box-line-break wrapper-d0Cc1k undefined">&nbsp;</div>
<ul class="auto-hide-last-sibling-br">
<li><strong>数字类型</strong>：优先用<code>INT</code>（4 字节）、<code>BIGINT</code>（8 字节）存整数，避免用<code>VARCHAR</code>（如用户 ID、订单号）；用<code>DECIMAL</code>存金额（如<code>DECIMAL(10,2)</code>），避免<code>FLOAT</code>/<code>DOUBLE</code>的精度丢失问题。</li>
<li><strong>字符串类型</strong>：固定长度用<code>CHAR</code>（如手机号 11 位用<code>CHAR(11)</code>），可变长度用<code>VARCHAR</code>（如用户名）；超长文本（如文章内容）用<code>TEXT</code>，但需注意：<code>TEXT</code>字段查询较慢，尽量避免作为查询条件。</li>
<li><strong>日期类型</strong>：用<code>DATE</code>（年月日）、<code>DATETIME</code>（年月日时分秒）、<code>TIMESTAMP</code>（带时区，占 4 字节，比<code>DATETIME</code>更省空间），避免用<code>VARCHAR</code>存日期（无法直接做时间运算，如<code>WHERE create_time &gt; '2023-01-01'</code>）。</li>
<li><strong>枚举类型</strong>：固定可选值的字段用<code>ENUM</code>（如性别<code>ENUM('male','female','unknown')</code>），比<code>VARCHAR</code>更省空间且查询更快。</li>
</ul>
<h3 class="header-vfC6AV auto-hide-last-sibling-br">三、科学设计索引，加速查询</h3>
<div class="auto-hide-last-sibling-br paragraph-JOTKXA paragraph-element br-paragraph-space">索引是提升查询效率的核心，但过多索引会降低插入 / 更新性能（索引需同步维护），需 &ldquo;按需创建&rdquo;。</div>
<h4 class="header-vfC6AV auto-hide-last-sibling-br">1. 必建索引的场景</h4>
<ul class="auto-hide-last-sibling-br">
<li><strong>主键索引</strong>：每张表必须有主键（<code>PRIMARY KEY</code>），推荐用自增<code>INT</code>或<code>BIGINT</code>（避免 UUID 等无序值，防止页分裂）。</li>
<li><strong>外键索引</strong>：外键字段（如<code>order.product_id</code>关联<code>product.id</code>）需建索引，否则 JOIN 操作会全表扫描。</li>
<li><strong>高频查询字段</strong>：<code>WHERE</code>、<code>JOIN</code>、<code>ORDER BY</code>、<code>GROUP BY</code>中频繁出现的字段，如用户表的<code>phone</code>（登录查询）、订单表的<code>user_id</code>（查询用户所有订单）。</li>
</ul>
<h4 class="header-vfC6AV auto-hide-last-sibling-br">2. 优化索引结构</h4>
<ul class="auto-hide-last-sibling-br">
<li><strong>联合索引</strong>：多字段查询时，创建联合索引（需遵循 &ldquo;最左前缀原则&rdquo;）。
<div class="container-utlnW2 md-box-line-break wrapper-d0Cc1k undefined">&nbsp;</div>
例：频繁查询<code>WHERE status=1 AND create_time &gt; '2023-01-01'</code>，联合索引<code>(status, create_time)</code>有效，而<code>(create_time, status)</code>无效（不符合最左前缀）。</li>
<li><strong>避免冗余索引</strong>：若已有联合索引<code>(a,b)</code>，则单独的<code>(a)</code>索引是冗余的（联合索引的前缀字段可被单独使用）。</li>
<li><strong>控制索引数量</strong>：单表索引建议不超过 5 个，新增索引前需评估查询收益与写入损耗。</li>
</ul>
<h4 class="header-vfC6AV auto-hide-last-sibling-br">3. 不适合建索引的场景</h4>
<ul class="auto-hide-last-sibling-br">
<li>低频查询字段（如一年才查一次的<code>remark</code>备注字段）；</li>
<li>字段值重复率高（如<code>gender</code>性别，区分度低，索引效果差）；</li>
<li>小表（数据量 &lt; 1 万行，全表扫描比索引查询更快）。</li>
</ul>
<h3 class="header-vfC6AV auto-hide-last-sibling-br">四、设计合理的关系与约束，保证数据完整性</h3>
<h4 class="header-vfC6AV auto-hide-last-sibling-br">1. 明确表关系（避免混乱关联）</h4>
<ul class="auto-hide-last-sibling-br">
<li><strong>一对一</strong>：如<code>user</code>与<code>user_passport</code>（一个用户对应一个护照），可将其中一张表的主键设为另一张表的外键（并加唯一约束<code>UNIQUE</code>）。</li>
<li><strong>一对多</strong>：如<code>user</code>与<code>order</code>（一个用户多个订单），在 &ldquo;多&rdquo; 的表（<code>order</code>）中加外键<code>user_id</code>关联<code>user.id</code>。</li>
<li><strong>多对多</strong>：如<code>student</code>与<code>course</code>（一个学生选多门课，一门课有多个学生），需创建中间表<code>student_course</code>，存储<code>student_id</code>和<code>course_id</code>（联合主键）。</li>
</ul>
<h4 class="header-vfC6AV auto-hide-last-sibling-br">2. 合理使用约束（减少脏数据）</h4>
<ul class="auto-hide-last-sibling-br">
<li><strong>非空约束（NOT NULL）</strong>：必填字段（如<code>user.name</code>、<code>order.amount</code>）设为<code>NOT NULL</code>，避免<code>NULL</code>值导致的查询异常（如<code>NULL != NULL</code>）。</li>
<li><strong>唯一约束（UNIQUE）</strong>：需唯一的字段（如<code>user.phone</code>、<code>product.sku</code>）设为<code>UNIQUE</code>，数据库层面防止重复。</li>
<li><strong>检查约束（CHECK）</strong>：限制字段值范围（如<code>order.amount &gt; 0</code>、<code>user.age BETWEEN 0 AND 150</code>），避免无效数据。</li>
</ul>
<h3 class="header-vfC6AV auto-hide-last-sibling-br">五、针对大数据量的特殊优化</h3>
<h4 class="header-vfC6AV auto-hide-last-sibling-br">1. 分区表（拆分大表为逻辑子表）</h4>
<div class="auto-hide-last-sibling-br paragraph-JOTKXA paragraph-element br-paragraph-space">当单表数据量超千万行，可使用分区表（MySQL 5.7+、PostgreSQL 等支持），按规则将数据分散到多个物理文件：</div>
<div class="container-utlnW2 md-box-line-break wrapper-d0Cc1k undefined">&nbsp;</div>
<ul class="auto-hide-last-sibling-br">
<li><strong>范围分区</strong>：按时间（如<code>create_time</code>）或数字范围（如<code>user_id</code>）分区，适合日志、订单等时序数据。
<div class="container-utlnW2 md-box-line-break wrapper-d0Cc1k undefined">&nbsp;</div>
例：<code>CREATE TABLE order (id INT, create_time DATETIME) PARTITION BY RANGE (TO_DAYS(create_time)) (PARTITION p202301 VALUES LESS THAN (TO_DAYS('2023-02-01')));</code></li>
<li><strong>列表分区</strong>：按枚举值（如<code>area_id</code>）分区，适合地区、状态等固定分类数据。</li>
</ul>
<h4 class="header-vfC6AV auto-hide-last-sibling-br">2. 分库分表（突破单库性能瓶颈）</h4>
<div class="auto-hide-last-sibling-br paragraph-JOTKXA paragraph-element br-paragraph-space">当数据量超亿级，单库难以承载时，需通过中间件（如 Sharding-JDBC）实现分库分表：</div>
<div class="container-utlnW2 md-box-line-break wrapper-d0Cc1k undefined">&nbsp;</div>
<ul class="auto-hide-last-sibling-br">
<li><strong>水平分库</strong>：按用户 ID 哈希将数据分散到多个数据库（如<code>db_0</code>、<code>db_1</code>），降低单库压力。</li>
<li><strong>垂直分库</strong>：按业务模块拆分（如用户库、订单库、商品库），避免单库资源竞争。</li>
</ul>
<h3 class="header-vfC6AV auto-hide-last-sibling-br">六、适配查询模式，减少低效操作</h3>
<h4 class="header-vfC6AV auto-hide-last-sibling-br">1. 避免 &ldquo;大而全&rdquo; 的查询</h4>
<div class="auto-hide-last-sibling-br paragraph-JOTKXA paragraph-element br-paragraph-space">设计表时需预判查询场景，避免频繁使用<code>SELECT *</code>或复杂 JOIN：</div>
<div class="container-utlnW2 md-box-line-break wrapper-d0Cc1k undefined">&nbsp;</div>
<ul class="auto-hide-last-sibling-br">
<li>例：电商商品列表页只需<code>id</code>、<code>name</code>、<code>price</code>、<code>img_url</code>，则将这些字段放在<code>product</code>主表，而<code>description</code>（详情）、<code>specs</code>（规格）等字段放在子表，减少列表查询的数据传输量。</li>
</ul>
<h4 class="header-vfC6AV auto-hide-last-sibling-br">2. 优化分页与排序</h4>
<ul class="auto-hide-last-sibling-br">
<li>分页查询：避免<code>LIMIT 100000, 10</code>（会扫描前 100010 行），改用 &ldquo;基于主键的跳页&rdquo;（如<code>WHERE id &gt; 100000 LIMIT 10</code>）。</li>
<li>排序字段：确保<code>ORDER BY</code>的字段有索引，避免无索引排序导致的临时表或文件排序（性能极低）。</li>
</ul>
<h3 class="header-vfC6AV auto-hide-last-sibling-br">七、其他关键优化</h3>
<ul class="auto-hide-last-sibling-br">
<li><strong>避免使用触发器和存储过程</strong>：逻辑复杂时难以维护，且可能成为性能瓶颈（建议移至应用层实现）。</li>
<li><strong>预留扩展字段</strong>：对变化频繁的业务（如用户标签），可预留<code>ext_json</code>字段（存储 JSON 格式的动态数据），避免频繁 ALTER TABLE（锁表影响性能）。</li>
<li><strong>定期维护</strong>：通过<code>EXPLAIN</code>分析慢查询，重建碎片化索引（<code>OPTIMIZE TABLE</code>），归档历史数据（如将 3 年前的订单迁移至历史库）。</li>
</ul>
<h3 class="header-vfC6AV auto-hide-last-sibling-br">总结</h3>
<div class="auto-hide-last-sibling-br paragraph-JOTKXA paragraph-element br-paragraph-space">数据库设计优化的核心是 **&ldquo;平衡&rdquo;**：在冗余与关联、查询效率与写入性能、简洁性与扩展性之间找到适合业务的平衡点。设计前需充分调研业务场景（如 OLTP 系统侧重写入和事务，OLAP 系统侧重查询和分析），设计后通过压测和监控持续迭代优化。</div>]]></description>
    <pubDate>Thu, 09 Oct 2025 17:33:39 +0800</pubDate>
    <dc:creator>neal</dc:creator>
    <guid>https://top.zhongtongzttb.com.cn/?post=76</guid>
</item>
<item>
    <title>工具Navicat连接MySQL的常见报错及处理方法</title>
    <link>https://top.zhongtongzttb.com.cn/?post=75</link>
    <description><![CDATA[<div class="auto-hide-last-sibling-br paragraph-JOTKXA paragraph-element br-paragraph-space">在使用 Navicat 连接 MySQL 时，常见报错通常与&nbsp;<strong>网络连接、MySQL 服务状态、账号权限、配置参数</strong>&nbsp;等相关。以下是按报错场景分类的常见问题、原因分析及详细处理方法，帮助快速定位并解决问题。</div>
<h3 class="header-vfC6AV auto-hide-last-sibling-br">一、基础连接类报错（最常见）</h3>
<div class="auto-hide-last-sibling-br paragraph-JOTKXA paragraph-element br-paragraph-space">此类报错核心原因：MySQL 服务未启动、端口 / IP 错误、网络不通。</div>
<h4 class="header-vfC6AV auto-hide-last-sibling-br">1. 报错提示：<code>Can't connect to MySQL server on 'xxx.xxx.xxx.xxx' (10060)</code></h4>
<ul class="auto-hide-last-sibling-br">
<li>
<div class="auto-hide-last-sibling-br paragraph-JOTKXA paragraph-element br-paragraph-space"><strong>原因</strong>：目标 MySQL 服务器的 IP / 端口无法访问（网络不通或服务未启动）。</div>
<ul class="auto-hide-last-sibling-br">
<li>可能 1：MySQL 服务未在目标服务器上启动；</li>
<li>可能 2：服务器防火墙 / 安全组拦截了 MySQL 默认端口（3306）；</li>
<li>可能 3：Navicat 中填写的 IP 或端口错误（如端口被修改为非 3306）。</li>
</ul>
</li>
<li>
<div class="auto-hide-last-sibling-br paragraph-JOTKXA paragraph-element br-paragraph-space"><strong>处理步骤</strong>：</div>
<ol class="auto-hide-last-sibling-br">
<li><strong>检查 MySQL 服务状态</strong>（目标服务器操作）：
<ul class="auto-hide-last-sibling-br">
<li>Windows：打开「服务」（Win+R 输入&nbsp;<code>services.msc</code>），找到「MySQL」服务，确认状态为「正在运行」，若未运行则右键「启动」。</li>
<li>Linux：执行命令&nbsp;<code>systemctl status mysql</code>（或&nbsp;<code>mysqld</code>），若显示&nbsp;<code>inactive</code>，则执行&nbsp;<code>systemctl start mysql</code>&nbsp;启动服务。</li>
</ul>
</li>
<li><strong>验证 IP 和端口正确性</strong>：
<ul class="auto-hide-last-sibling-br">
<li>确认 Navicat「连接属性」中「主机」是目标服务器的正确 IP（本地连接用&nbsp;<code>localhost</code>&nbsp;或&nbsp;<code>127.0.0.1</code>，远程连接用公网 / 内网 IP）；</li>
<li>确认「端口」与 MySQL 配置一致（默认 3306，若修改过需填实际端口，可通过 MySQL 配置文件&nbsp;<code>my.cnf</code>/<code>my.ini</code>&nbsp;中的&nbsp;<code>port</code>&nbsp;项查看）。</li>
</ul>
</li>
<li><strong>测试网络连通性</strong>（本地电脑操作）：
<ul class="auto-hide-last-sibling-br">
<li>打开 CMD/PowerShell（Windows）或 Terminal（Mac/Linux），执行&nbsp;<code>ping 目标IP</code>，确认能 ping 通（排除 IP 错误或服务器离线）；</li>
<li>执行&nbsp;<code>telnet 目标IP 端口</code>（如&nbsp;<code>telnet 192.168.1.100 3306</code>），若提示「无法打开连接」，说明端口被拦截，需配置防火墙 / 安全组。</li>
</ul>
</li>
<li><strong>开放端口（服务器操作）</strong>：
<ul class="auto-hide-last-sibling-br">
<li>Windows：打开「高级防火墙设置」&rarr;「入站规则」&rarr;「新建规则」，选择「端口」，输入 3306，允许连接。</li>
<li>Linux（以 CentOS 为例）：执行&nbsp;<code>firewall-cmd --zone=public --add-port=3306/tcp --permanent</code>，再执行&nbsp;<code>firewall-cmd --reload</code>&nbsp;生效；若用云服务器（阿里云 / 腾讯云），需在「安全组」中添加「允许 3306 端口入站」规则。</li>
</ul>
</li>
</ol>
</li>
</ul>
<h4 class="header-vfC6AV auto-hide-last-sibling-br">2. 报错提示：<code>Access denied for user 'root'@'localhost' (using password: YES)</code></h4>
<ul class="auto-hide-last-sibling-br">
<li>
<div class="auto-hide-last-sibling-br paragraph-JOTKXA paragraph-element br-paragraph-space"><strong>原因</strong>：账号密码错误，或账号不允许在当前主机（<a class="link-ZNPgAX" href="https://localhost/" target="_blank" rel="noopener">localhost/</a>远程 IP）登录。</div>
<ul class="auto-hide-last-sibling-br">
<li>可能 1：Navicat 中输入的「用户名」或「密码」错误（如密码大小写错误、遗忘密码）；</li>
<li>可能 2：账号仅允许特定 IP 登录（如&nbsp;<code>root</code>&nbsp;默认仅允许&nbsp;<code>localhost</code>&nbsp;登录，远程连接时被拒绝）。</li>
</ul>
</li>
<li>
<div class="auto-hide-last-sibling-br paragraph-JOTKXA paragraph-element br-paragraph-space"><strong>处理步骤</strong>：</div>
<ol class="auto-hide-last-sibling-br">
<li><strong>验证账号密码正确性</strong>：
<ul class="auto-hide-last-sibling-br">
<li>直接在 MySQL 服务器上登录验证：Windows 打开「MySQL Command Line Client」，Linux 执行&nbsp;<code>mysql -u 用户名 -p</code>，输入密码后若能登录，说明密码正确（否则需重置密码）。</li>
</ul>
</li>
<li><strong>重置遗忘的密码</strong>（以 root 账号为例）：
<ul class="auto-hide-last-sibling-br">
<li>Windows：
<ol class="auto-hide-last-sibling-br">
<li>停止 MySQL 服务（服务中右键「停止」）；</li>
<li>打开 CMD，切换到 MySQL 的&nbsp;<code>bin</code>&nbsp;目录（如&nbsp;<code>cd C:\Program Files\MySQL\MySQL Server 8.0\bin</code>）；</li>
<li>执行&nbsp;<code>mysqld --console --skip-grant-tables --shared-memory</code>（跳过权限验证启动服务）；</li>
<li>新打开一个 CMD，执行&nbsp;<code>mysql -u root</code>（无密码登录）；</li>
<li>执行命令更新密码：
<div class="code-block-element-YDlfvc light custom-code-block-container--sql hide-indicator disable-theme-style custom-code-block-container">
<div class="code-area-tZtDgG code-area" dir="ltr">
<div class="header-wrapper-UnnlXS">
<div class="header-cGu84a">
<div class="title-XQhI4x clickable-eGISjP" tabindex="0" aria-describedby="rvr627k" data-popupid="rvr627k">
<div class="text-jgT4jF">sql</div>
<div class="icon-FIfuuc">&nbsp;</div>
</div>
<div class="action-tEcs3i">
<div class="hoverable-sPLxOT" tabindex="0" data-testid="code-block-copy" aria-describedby="yozu559" data-popupid="yozu559">&nbsp;</div>
<div class="hoverable-sPLxOT" tabindex="0" aria-describedby="9425egj" data-popupid="9425egj">&nbsp;</div>
<div class="hoverable-sPLxOT" tabindex="0" aria-describedby="5ivr42u" data-popupid="5ivr42u">&nbsp;</div>
<div class="hoverable-sPLxOT" tabindex="0" aria-describedby="s4i06v8" data-popupid="s4i06v8">&nbsp;</div>
</div>
</div>
</div>
<div class="content-EGRozu code-content light-scrollbar-TbsSwi">
<pre class="container-_HmLba language-sql"><code>FLUSH PRIVILEGES; -- 刷新权限
ALTER USER 'root'@'localhost' IDENTIFIED BY '新密码'; -- 重置本地密码
</code></pre>
</div>
<div class="mask-wrapper-VgpgeU">
<div class="mask-ZLHDuN">&nbsp;</div>
</div>
</div>
</div>
<div class="container-utlnW2 md-box-line-break wrapper-d0Cc1k undefined">&nbsp;</div>
</li>
<li>关闭所有 CMD 窗口，重启 MySQL 服务，用新密码连接。</li>
</ol>
</li>
<li>Linux：
<ol class="auto-hide-last-sibling-br">
<li>执行&nbsp;<code>systemctl stop mysql</code>&nbsp;停止服务；</li>
<li>执行&nbsp;<code>mysqld_safe --skip-grant-tables &amp;</code>&nbsp;跳过权限启动；</li>
<li>执行&nbsp;<code>mysql -u root</code>&nbsp;登录，后续步骤与 Windows 一致（第 5 步相同 SQL）。</li>
</ol>
</li>
</ul>
</li>
<li><strong>允许账号远程登录</strong>（若为远程连接场景）：
<ul class="auto-hide-last-sibling-br">
<li>登录 MySQL 后，执行以下 SQL，允许&nbsp;<code>root</code>&nbsp;账号从任意 IP 登录（或指定 IP，将&nbsp;<code>%</code>&nbsp;改为具体 IP）：
<div class="code-block-element-YDlfvc light custom-code-block-container--sql hide-indicator disable-theme-style custom-code-block-container">
<div class="code-area-tZtDgG code-area" dir="ltr">
<div class="header-wrapper-UnnlXS">
<div class="header-cGu84a">
<div class="title-XQhI4x clickable-eGISjP" tabindex="0" aria-describedby="i3r9jth" data-popupid="i3r9jth">
<div class="text-jgT4jF">sql</div>
<div class="icon-FIfuuc">&nbsp;</div>
</div>
<div class="action-tEcs3i">
<div class="hoverable-sPLxOT" tabindex="0" data-testid="code-block-copy" aria-describedby="bzwpnsz" data-popupid="bzwpnsz">&nbsp;</div>
<div class="hoverable-sPLxOT" tabindex="0" aria-describedby="n87svvl" data-popupid="n87svvl">&nbsp;</div>
<div class="hoverable-sPLxOT" tabindex="0" aria-describedby="4k46bni" data-popupid="4k46bni">&nbsp;</div>
<div class="hoverable-sPLxOT" tabindex="0" aria-describedby="iss5u2r" data-popupid="iss5u2r">&nbsp;</div>
</div>
</div>
</div>
<div class="content-EGRozu code-content light-scrollbar-TbsSwi">
<pre class="container-_HmLba language-sql"><code>CREATE USER 'root'@'%' IDENTIFIED BY '密码'; -- 新建远程账号（若不存在）
GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' WITH GRANT OPTION; -- 赋予远程权限
FLUSH PRIVILEGES; -- 刷新权限
</code></pre>
</div>
<div class="mask-wrapper-VgpgeU">
<div class="mask-ZLHDuN">&nbsp;</div>
</div>
</div>
</div>
<div class="container-utlnW2 md-box-line-break wrapper-d0Cc1k undefined">&nbsp;</div>
</li>
</ul>
</li>
</ol>
</li>
</ul>
<h3 class="header-vfC6AV auto-hide-last-sibling-br">二、MySQL 版本与配置兼容类报错</h3>
<div class="auto-hide-last-sibling-br paragraph-JOTKXA paragraph-element br-paragraph-space">此类报错多因 MySQL 8.0+ 版本的新特性（如密码加密方式）与 Navicat 旧版本不兼容，或配置参数限制。</div>
<h4 class="header-vfC6AV auto-hide-last-sibling-br">1. 报错提示：<code>Authentication plugin 'caching_sha2_password' cannot be loaded</code></h4>
<ul class="auto-hide-last-sibling-br">
<li>
<div class="auto-hide-last-sibling-br paragraph-JOTKXA paragraph-element br-paragraph-space"><strong>原因</strong>：MySQL 8.0+ 默认使用&nbsp;<code>caching_sha2_password</code>&nbsp;加密方式，而 Navicat 12 及以下版本不支持该加密方式（仅支持旧版&nbsp;<code>mysql_native_password</code>）。</div>
</li>
<li>
<div class="auto-hide-last-sibling-br paragraph-JOTKXA paragraph-element br-paragraph-space"><strong>处理步骤</strong>：</div>
<ol class="auto-hide-last-sibling-br">
<li><strong>方案 1：升级 Navicat</strong>（推荐）：
<ul class="auto-hide-last-sibling-br">
<li>下载 Navicat 15+ 版本（官网或可信渠道），新版本已支持&nbsp;<code>caching_sha2_password</code>&nbsp;加密，直接连接即可。</li>
</ul>
</li>
<li><strong>方案 2：修改 MySQL 账号加密方式</strong>（兼容旧 Navicat）：
<ul class="auto-hide-last-sibling-br">
<li>登录 MySQL 后，执行以下 SQL，将账号加密方式改为&nbsp;<code>mysql_native_password</code>：
<div class="code-block-element-YDlfvc light custom-code-block-container--sql hide-indicator disable-theme-style custom-code-block-container">
<div class="code-area-tZtDgG code-area" dir="ltr">
<div class="header-wrapper-UnnlXS">
<div class="header-cGu84a">
<div class="title-XQhI4x clickable-eGISjP" tabindex="0" aria-describedby="v856w2a" data-popupid="v856w2a">
<div class="text-jgT4jF">sql</div>
<div class="icon-FIfuuc">&nbsp;</div>
</div>
<div class="action-tEcs3i">
<div class="hoverable-sPLxOT" tabindex="0" data-testid="code-block-copy" aria-describedby="6gpys1u" data-popupid="6gpys1u">&nbsp;</div>
<div class="hoverable-sPLxOT" tabindex="0" aria-describedby="169s50i" data-popupid="169s50i">&nbsp;</div>
<div class="hoverable-sPLxOT" tabindex="0" aria-describedby="0jyhf2w" data-popupid="0jyhf2w">&nbsp;</div>
<div class="hoverable-sPLxOT" tabindex="0" aria-describedby="cnqphhn" data-popupid="cnqphhn">&nbsp;</div>
</div>
</div>
</div>
<div class="content-EGRozu code-content light-scrollbar-TbsSwi">
<pre class="container-_HmLba language-sql"><code>-- 查看当前账号加密方式
SELECT user, host, plugin FROM mysql.user WHERE user = 'root';
-- 修改加密方式并重置密码
ALTER USER 'root'@'%' IDENTIFIED WITH mysql_native_password BY '你的密码';
FLUSH PRIVILEGES; -- 刷新权限
</code></pre>
</div>
<div class="mask-wrapper-VgpgeU">
<div class="mask-ZLHDuN">&nbsp;</div>
</div>
</div>
</div>
<div class="container-utlnW2 md-box-line-break wrapper-d0Cc1k undefined">&nbsp;</div>
</li>
<li>重启 Navicat，重新连接即可。</li>
</ul>
</li>
</ol>
</li>
</ul>
<h4 class="header-vfC6AV auto-hide-last-sibling-br">2. 报错提示：<code>Too many connections</code></h4>
<ul class="auto-hide-last-sibling-br">
<li>
<div class="auto-hide-last-sibling-br paragraph-JOTKXA paragraph-element br-paragraph-space"><strong>原因</strong>：MySQL 允许的最大连接数（<code>max_connections</code>）已达上限，无法新建立连接。</div>
</li>
<li>
<div class="auto-hide-last-sibling-br paragraph-JOTKXA paragraph-element br-paragraph-space"><strong>处理步骤</strong>：</div>
<ol class="auto-hide-last-sibling-br">
<li><strong>临时调整最大连接数</strong>（立即生效，重启服务后失效）：
<ul class="auto-hide-last-sibling-br">
<li>登录 MySQL，执行&nbsp;<code>SET GLOBAL max_connections = 1000;</code>（默认通常为 151，可根据需求调整）；</li>
<li>执行&nbsp;<code>SHOW VARIABLES LIKE 'max_connections';</code>&nbsp;验证是否修改成功。</li>
</ul>
</li>
<li><strong>永久调整最大连接数</strong>（需修改配置文件）：
<ul class="auto-hide-last-sibling-br">
<li>Windows：找到 MySQL 配置文件&nbsp;<code>my.ini</code>（通常在&nbsp;<code>C:\ProgramData\MySQL\MySQL Server 8.0</code>），在&nbsp;<code>[mysqld]</code>&nbsp;下添加&nbsp;<code>max_connections = 1000</code>，保存后重启 MySQL 服务。</li>
<li>Linux：找到配置文件&nbsp;<code>my.cnf</code>（通常在&nbsp;<code>/etc/mysql/</code>），同样在&nbsp;<code>[mysqld]</code>&nbsp;下添加&nbsp;<code>max_connections = 1000</code>，执行&nbsp;<code>systemctl restart mysql</code>&nbsp;重启服务。</li>
</ul>
</li>
<li><strong>排查连接泄漏</strong>：
<ul class="auto-hide-last-sibling-br">
<li>执行&nbsp;<code>SHOW PROCESSLIST;</code>&nbsp;查看当前所有连接，若存在大量闲置连接，可执行&nbsp;<code>KILL 连接ID;</code>&nbsp;关闭（连接 ID 对应&nbsp;<code>Id</code>&nbsp;列的值）。</li>
</ul>
</li>
</ol>
</li>
</ul>
<h3 class="header-vfC6AV auto-hide-last-sibling-br">三、文件权限与服务异常类报错</h3>
<div class="auto-hide-last-sibling-br paragraph-JOTKXA paragraph-element br-paragraph-space">此类报错与 MySQL 服务依赖的文件权限、配置文件错误相关。</div>
<h4 class="header-vfC6AV auto-hide-last-sibling-br">1. 报错提示：<code>MySQL server version for the right syntax to use near...</code></h4>
<ul class="auto-hide-last-sibling-br">
<li>
<div class="auto-hide-last-sibling-br paragraph-JOTKXA paragraph-element br-paragraph-space"><strong>原因</strong>：Navicat 执行的 SQL 语句语法与 MySQL 版本不兼容（如 MySQL 5.x 与 8.0 的语法差异）。</div>
<ul class="auto-hide-last-sibling-br">
<li>示例：MySQL 8.0 不支持&nbsp;<code>PASSWORD()</code>&nbsp;函数（用于加密密码），若执行&nbsp;<code>SELECT PASSWORD('123456');</code>&nbsp;会报错。</li>
</ul>
</li>
<li>
<div class="auto-hide-last-sibling-br paragraph-JOTKXA paragraph-element br-paragraph-space"><strong>处理步骤</strong>：</div>
<ol class="auto-hide-last-sibling-br">
<li>确认 MySQL 版本：登录 MySQL 后执行&nbsp;<code>SELECT VERSION();</code>&nbsp;查看版本；</li>
<li>调整 SQL 语法以适配版本：
<ul class="auto-hide-last-sibling-br">
<li>如密码加密：MySQL 5.x 用&nbsp;<code>PASSWORD('密码')</code>，MySQL 8.0 用&nbsp;<code>SHA2('密码', 256)</code>&nbsp;或&nbsp;<code>ALTER USER</code>&nbsp;语句；</li>
<li>如&nbsp;<code>GROUP BY</code>&nbsp;语法：MySQL 5.7+ 默认开启&nbsp;<code>only_full_group_by</code>&nbsp;模式，需确保&nbsp;<code>GROUP BY</code>&nbsp;后的字段包含非聚合列，或执行&nbsp;<code>SET sql_mode = '';</code>&nbsp;临时关闭该模式（永久关闭需修改配置文件&nbsp;<code>my.cnf</code>/<code>my.ini</code>，添加&nbsp;<code>sql_mode = ""</code>）。</li>
</ul>
</li>
</ol>
</li>
</ul>
<h4 class="header-vfC6AV auto-hide-last-sibling-br">2. 报错提示：<code>The server is configured with lower_case_table_names=0 ...</code></h4>
<ul class="auto-hide-last-sibling-br">
<li>
<div class="auto-hide-last-sibling-br paragraph-JOTKXA paragraph-element br-paragraph-space"><strong>原因</strong>：MySQL 配置的&nbsp;<code>lower_case_table_names</code>（表名大小写敏感）参数与操作系统不匹配，导致表名识别错误。</div>
<ul class="auto-hide-last-sibling-br">
<li>Windows 系统默认&nbsp;<code>lower_case_table_names=1</code>（表名不区分大小写）；</li>
<li>Linux 系统默认&nbsp;<code>lower_case_table_names=0</code>（表名区分大小写）；</li>
<li>若手动修改该参数后未正确重启，或跨系统迁移数据库，会出现此报错。</li>
</ul>
</li>
<li>
<div class="auto-hide-last-sibling-br paragraph-JOTKXA paragraph-element br-paragraph-space"><strong>处理步骤</strong>：</div>
<ol class="auto-hide-last-sibling-br">
<li>停止 MySQL 服务；</li>
<li>修改配置文件&nbsp;<code>my.cnf</code>（Linux）或&nbsp;<code>my.ini</code>（Windows）：
<ul class="auto-hide-last-sibling-br">
<li>Windows：在&nbsp;<code>[mysqld]</code>&nbsp;下添加&nbsp;<code>lower_case_table_names=1</code>；</li>
<li>Linux：若需表名不区分大小写，添加&nbsp;<code>lower_case_table_names=1</code>（需确保数据库目录下无已存在的表，否则需迁移数据后修改）；</li>
</ul>
</li>
<li>保存配置文件，重启 MySQL 服务，重新连接。</li>
</ol>
</li>
</ul>
<h3 class="header-vfC6AV auto-hide-last-sibling-br">四、其他小众但关键的报错</h3>
<h4 class="header-vfC6AV auto-hide-last-sibling-br">1. 报错提示：<code>Lost connection to MySQL server at 'reading initial communication packet', system error: 0</code></h4>
<ul class="auto-hide-last-sibling-br">
<li><strong>原因</strong>：MySQL 服务器的&nbsp;<code>bind-address</code>&nbsp;配置限制了仅允许特定 IP 连接，或网络不稳定导致握手失败。</li>
<li><strong>处理步骤</strong>：
<ol class="auto-hide-last-sibling-br">
<li>修改 MySQL 配置文件&nbsp;<code>my.cnf</code>/<code>my.ini</code>，找到&nbsp;<code>bind-address</code>&nbsp;项：
<ul class="auto-hide-last-sibling-br">
<li>若为远程连接，将&nbsp;<code>bind-address = 127.0.0.1</code>&nbsp;改为&nbsp;<code>bind-address = 0.0.0.0</code>（允许所有 IP 连接）；</li>
</ul>
</li>
<li>保存后重启 MySQL 服务，重新测试连接。</li>
</ol>
</li>
</ul>
<h4 class="header-vfC6AV auto-hide-last-sibling-br">2. 报错提示：<code>Navicat 连接超时</code>（无具体代码，仅提示超时）</h4>
<ul class="auto-hide-last-sibling-br">
<li><strong>原因</strong>：MySQL 服务响应慢，或 Navicat 连接超时设置过短。</li>
<li><strong>处理步骤</strong>：
<ol class="auto-hide-last-sibling-br">
<li>在 Navicat「连接属性」&rarr;「高级」中，将「连接超时」从默认的 10 秒改为 30 秒或更长；</li>
<li>检查 MySQL 服务器负载（如 CPU、内存使用率），若负载过高，需优化 SQL 或升级服务器配置。</li>
</ol>
</li>
</ul>
<h3 class="header-vfC6AV auto-hide-last-sibling-br">五、排查通用步骤（所有报错通用）</h3>
<div class="auto-hide-last-sibling-br paragraph-JOTKXA paragraph-element br-paragraph-space">若遇到上述未覆盖的报错，可按以下步骤逐步排查：</div>
<div class="container-utlnW2 md-box-line-break wrapper-d0Cc1k undefined">&nbsp;</div>
<ol class="auto-hide-last-sibling-br">
<li><strong>确认基础环境</strong>：MySQL 服务是否启动、IP / 端口是否正确、网络是否通畅（用&nbsp;<code>ping</code>&nbsp;和&nbsp;<code>telnet</code>&nbsp;验证）；</li>
<li><strong>验证账号权限</strong>：在 MySQL 服务器本地登录账号，确认密码正确且有连接权限；</li>
<li><strong>查看 MySQL 日志</strong>：日志中会记录详细错误原因（路径在配置文件&nbsp;<code>my.cnf</code>/<code>my.ini</code>&nbsp;的&nbsp;<code>log-error</code>&nbsp;项中）；</li>
<li><strong>升级软件版本</strong>：若为版本兼容问题，升级 Navicat 或 MySQL 到稳定版本（如 MySQL 8.0+ 搭配 Navicat 15+）。</li>
</ol>
<div class="container-utlnW2 md-box-line-break wrapper-d0Cc1k undefined">&nbsp;</div>
<div class="auto-hide-last-sibling-br paragraph-JOTKXA paragraph-element br-paragraph-space">通过以上方法，可解决 95% 以上的 Navicat 连接 MySQL 报错问题。</div>]]></description>
    <pubDate>Thu, 09 Oct 2025 14:32:57 +0800</pubDate>
    <dc:creator>neal</dc:creator>
    <guid>https://top.zhongtongzttb.com.cn/?post=75</guid>
</item>
<item>
    <title>怎么在宝塔里边部署静态网页</title>
    <link>https://top.zhongtongzttb.com.cn/?post=74</link>
    <description><![CDATA[<div class="auto-hide-last-sibling-br paragraph-JOTKXA paragraph-element br-paragraph-space">在宝塔面板中部署静态网页是一个相对简单的过程，以下是详细步骤：</div>
<div class="container-utlnW2 md-box-line-break wrapper-d0Cc1k undefined">&nbsp;</div>
<ol class="auto-hide-last-sibling-br">
<li>
<div class="auto-hide-last-sibling-br paragraph-JOTKXA paragraph-element br-paragraph-space"><strong>登录宝塔面板</strong></div>
<ul class="auto-hide-last-sibling-br">
<li>通过服务器 IP:8888 访问宝塔登录页面</li>
<li>输入用户名和密码登录</li>
</ul>
</li>
<li>
<div class="auto-hide-last-sibling-br paragraph-JOTKXA paragraph-element br-paragraph-space"><strong>创建网站</strong></div>
<ul class="auto-hide-last-sibling-br">
<li>在左侧菜单找到「网站」并点击</li>
<li>点击「添加站点」按钮</li>
<li>填写域名（如果没有域名，可填写服务器 IP）</li>
<li>根目录可保持默认或自定义（建议使用默认路径）</li>
<li>静态网页无需数据库，所以数据库选项选择「无」</li>
<li>PHP 版本选择「纯静态」</li>
<li>点击「提交」完成网站创建</li>
</ul>
</li>
<li>
<div class="auto-hide-last-sibling-br paragraph-JOTKXA paragraph-element br-paragraph-space"><strong>上传静态文件</strong></div>
<ul class="auto-hide-last-sibling-br">
<li>网站创建完成后，点击该网站的「文件」按钮进入文件管理</li>
<li>进入网站根目录（通常是 /www/wwwroot/ 你的域名）</li>
<li>删除目录中默认的文件（如 index.html、404.html 等）</li>
<li>点击「上传」按钮，选择你的静态网页文件（HTML、CSS、JS、图片等）</li>
<li>可以选择上传压缩包后解压，或直接上传整个文件夹</li>
</ul>
</li>
<li>
<div class="auto-hide-last-sibling-br paragraph-JOTKXA paragraph-element br-paragraph-space"><strong>设置默认首页</strong></div>
<ul class="auto-hide-last-sibling-br">
<li>回到网站列表，点击该网站的「设置」</li>
<li>进入「默认文档」选项卡</li>
<li>确保你的首页文件（通常是 index.html）在默认文档列表中，并且位于靠前位置</li>
<li>点击「保存」</li>
</ul>
</li>
<li>
<div class="auto-hide-last-sibling-br paragraph-JOTKXA paragraph-element br-paragraph-space"><strong>访问网站</strong></div>
<ul class="auto-hide-last-sibling-br">
<li>在浏览器中输入你的域名或服务器 IP</li>
<li>如果配置正确，应该能看到你的静态网页内容</li>
</ul>
</li>
</ol>
<div class="container-utlnW2 md-box-line-break wrapper-d0Cc1k undefined">&nbsp;</div>
<div class="auto-hide-last-sibling-br paragraph-JOTKXA paragraph-element br-paragraph-space">注意事项：</div>
<div class="container-utlnW2 md-box-line-break wrapper-d0Cc1k undefined">&nbsp;</div>
<ul class="auto-hide-last-sibling-br">
<li>确保文件名和路径正确，特别是引用 CSS、JS 和图片的路径</li>
<li>如果使用了路由功能，可能需要配置伪静态规则</li>
<li>若网页涉及跨域请求，可能需要在宝塔的 Nginx 配置中添加跨域允许规则</li>
</ul>
<div class="container-utlnW2 md-box-line-break wrapper-d0Cc1k undefined">&nbsp;</div>
<div class="auto-hide-last-sibling-br paragraph-JOTKXA paragraph-element br-paragraph-space">按照以上步骤，你应该能够顺利在宝塔面板中部署静态网页。</div>]]></description>
    <pubDate>Sat, 27 Sep 2025 11:44:15 +0800</pubDate>
    <dc:creator>neal</dc:creator>
    <guid>https://top.zhongtongzttb.com.cn/?post=74</guid>
</item>
<item>
    <title>Python怎么从网页上爬数据</title>
    <link>https://top.zhongtongzttb.com.cn/?post=73</link>
    <description><![CDATA[<p>太好了！你想学习Python爬虫，这是一个非常实用且有趣的技能。我来为你提供一个从零开始的、全面的入门指南。</p>
<p>核心思想：爬虫是什么？</p>
<p>简单来说，网络爬虫就是一个自动化的程序，它模仿人类浏览网页的行为，但速度更快、规模更大。它的基本工作流程是：<br>1. &nbsp;**发送请求**：向目标网站的服务器发送一个请求（比如&ldquo;请把百度首页的内容给我&rdquo;）。<br>2. &nbsp;**获取响应**：服务器返回网页的源代码（通常是HTML格式）。<br>3. &nbsp;**解析数据**：从一大堆HTML代码中，提取出我们需要的具体信息（如文章标题、价格、链接等）。<br>4. &nbsp;**保存数据**：将提取出的信息保存到文件（如CSV、JSON）或数据库中。</p>
<p>---</p>
<p>&nbsp;第一步：必备库介绍</p>
<p>Python有几个库是爬虫的&ldquo;神器&rdquo;，你需要先安装它们。</p>
<p>```bash<br># 在命令行/终端中使用pip安装<br>pip install requests<br>pip install beautifulsoup4<br>pip install lxml &nbsp;# 这是一个解析器，BeautifulSoup需要它来快速解析HTML<br>```</p>
<p>- **`requests`**： 用于发送HTTP请求，获取网页源代码。简单易用，是爬虫的基础。<br>- **`BeautifulSoup`** (来自 `bs4`)： 用于解析HTML和XML文档，从复杂的标签中提取数据，就像在汤里捞取你想要的&ldquo;菜&rdquo;（数据）一样，故名&ldquo;美丽的汤&rdquo;。</p>
<p>---</p>
<p>第二步：一个完整的入门实例（静态页面爬取）</p>
<p>我们以爬取**豆瓣电影Top250**的第一页电影名和评分为例。</p>
<p>```python<br>import requests<br>from bs4 import BeautifulSoup</p>
<p># 1. 目标网址<br>url = 'https://movie.douban.com/top250'</p>
<p># 2. 模拟浏览器访问（添加请求头，避免被网站识别为简单爬虫）<br>headers = {<br>&nbsp; &nbsp; 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36'<br>}</p>
<p># 3. 发送GET请求，获取网页源代码<br>response = requests.get(url, headers=headers)<br># 检查请求是否成功（状态码200表示成功）<br>if response.status_code == 200:<br>&nbsp; &nbsp; html_text = response.text &nbsp;# 得到网页的HTML文本<br>else:<br>&nbsp; &nbsp; print(&lsquo;请求失败，状态码：', response.status_code)<br>&nbsp; &nbsp; exit()</p>
<p># 4. 使用BeautifulSoup解析HTML<br>soup = BeautifulSoup(html_text, 'lxml') &nbsp;# 指定使用lxml解析器</p>
<p># 5. 查找和提取数据<br># 在浏览器中打开豆瓣Top250，按F12打开开发者工具，使用&ldquo;检查&rdquo;功能找到电影名所在的HTML标签。<br># 我们发现每个电影项都在一个 class="item" 的div中，电影名在 &lt;span class="title"&gt; 里。<br>movie_list = soup.find_all('div', class_='item')</p>
<p>for movie in movie_list:<br>&nbsp; &nbsp; # 查找电影名（只取中文名，第一个span.title）<br>&nbsp; &nbsp; title_tag = movie.find('span', class_='title')<br>&nbsp; &nbsp; title = title_tag.get_text() if title_tag else "未找到标题"</p>
<p>&nbsp; &nbsp; # 查找评分（在 &lt;span class="rating_num"&gt; 里）<br>&nbsp; &nbsp; rating_tag = movie.find('span', class_='rating_num')<br>&nbsp; &nbsp; rating = rating_tag.get_text() if rating_tag else "未找到评分"</p>
<p>&nbsp; &nbsp; # 6. 打印结果<br>&nbsp; &nbsp; print(f"电影：{title}， 评分：{rating}")</p>
<p>print("爬取完成！")<br>```</p>
<p>**运行这段代码，你就能看到第一页25部电影的名称和评分了！**</p>
<p>---</p>
<p>第三步：关键技巧与概念</p>
<p>1. 如何找到需要的数据？（核心技能）<br>这是爬虫最关键的一步。你需要使用浏览器的**开发者工具（按F12）**。<br>- 在网页上右键点击你想爬取的内容（比如电影名），选择&ldquo;检查&rdquo;或&ldquo;审查元素&rdquo;。<br>- 开发者工具会高亮显示对应的HTML代码。<br>- 观察它的标签（如 `div`, `span`, `a`）和属性（特别是 `class` 和 `id`），然后用 `find` 或 `find_all` 来定位。</p>
<p>&nbsp;2. 处理动态加载的内容（Ajax）<br>有些网站（如淘宝、微博）的内容是通过JavaScript动态加载的，直接用 `requests.get()` 得到的HTML里没有这些内容。这时你有两个选择：</p>
<p>- **方案A：找Ajax接口**<br>&nbsp; &nbsp; - 按F12打开&ldquo;网络(Network)&rdquo;选项卡。<br>&nbsp; &nbsp; - 刷新页面，筛选XHR或JS类型的请求。<br>&nbsp; &nbsp; - 找到真正包含数据的请求，这个接口返回的往往是JSON格式，直接用 `requests` 请求这个接口会更简单。</p>
<p>- **方案B：使用Selenium**<br>&nbsp; &nbsp; - `Selenium` 是一个自动化测试工具，可以模拟真实浏览器操作（点击、滚动等）。<br>&nbsp; &nbsp; - 它能等到JavaScript执行完毕后再获取页面内容，但速度较慢。<br>&nbsp; &nbsp; ```python<br>&nbsp; &nbsp; from selenium import webdriver<br>&nbsp; &nbsp; driver = webdriver.Chrome() &nbsp;# 需要先下载ChromeDriver<br>&nbsp; &nbsp; driver.get(url)<br>&nbsp; &nbsp; page_source = driver.page_source &nbsp;# 此时已包含动态加载的内容<br>&nbsp; &nbsp; # ... 然后用BeautifulSoup解析page_source<br>&nbsp; &nbsp; driver.quit()<br>&nbsp; &nbsp; ```</p>
<p>3. 遵守规则，做&ldquo;好人&rdquo;<br>- **查看 `robots.txt`**：访问 `网站域名/robots.txt`（如 `https://www.douban.com/robots.txt`），看网站允许爬虫爬取哪些内容。<br>- **设置延迟**：在请求之间使用 `time.sleep(1)` 暂停一下，减轻服务器压力。<br>- **识别反爬虫机制**：常见的反爬措施有：<br>&nbsp; &nbsp; - **User-Agent检查**：我们上面已经通过添加 `headers` 解决了。<br>&nbsp; &nbsp; - **IP频率限制**：同一个IP短时间请求太多次会被封。解决方法：使用代理IP池。<br>&nbsp; &nbsp; - **验证码**：复杂情况下需要接入打码平台或使用机器学习识别。</p>
<p>---</p>
<p>第四步：进阶学习路径</p>
<p>1. &nbsp;**爬取多页数据**：分析翻页URL规律（如 `?start=25`），用循环遍历所有页面。<br>2. &nbsp;**保存数据**：将结果保存到文件。<br>&nbsp; &nbsp; - **CSV文件**：使用内置的 `csv` 模块。<br>&nbsp; &nbsp; - **JSON文件**：使用 `json` 模块。<br>&nbsp; &nbsp; - **数据库**：学习使用 `sqlite3`（轻量级）或 `pymysql`/`pymongo` 连接数据库。<br>3. &nbsp;**使用Scrapy框架**：当项目变得庞大复杂时，`Scrapy` 是一个专业的爬虫框架，它提供了强大的异步处理、管道、中间件等功能，效率远高于手动编写。<br>4. &nbsp;**学习正则表达式**：有时用正则表达式提取数据更灵活，可以配合 `re` 模块使用。</p>
<p>总结</p>
<p>| 步骤 | 核心操作 | 常用工具 |<br>| **1. 获取页面** | 发送HTTP请求 | `requests`， `selenium` |<br>| **2. 解析页面** | 从HTML/JSON中提取数据 | `BeautifulSoup`， `lxml`， `json` |<br>| **3. 存储数据** | 保存到文件或数据库 | `csv`， `json`， `pymysql` |</p>
<p>**给你的建议：**<br>从简单的静态网站（如豆瓣、知乎、新闻网站）开始练习，熟练掌握 `requests` + `BeautifulSoup` 这套组合拳。然后逐步挑战有动态内容、有反爬机制的网站。</p>
<p>祝你爬虫之旅愉快！记得要负责任地使用爬虫，尊重网站的规定。</p>]]></description>
    <pubDate>Tue, 23 Sep 2025 16:49:21 +0800</pubDate>
    <dc:creator>neal</dc:creator>
    <guid>https://top.zhongtongzttb.com.cn/?post=73</guid>
</item>
<item>
    <title>生活小妙招</title>
    <link>https://top.zhongtongzttb.com.cn/?post=72</link>
    <description><![CDATA[<div class="ai-entry-block" data-show-ext="">
<div id="1" class="cosd-markdown cos-space-mt-lg">
<div class="cosd-markdown-content cosd-markdown-content-typingall">
<div class="marklang">
<h3>一、家居清洁类</h3>
<ol>
<li>&zwnj;<strong>大米清洁窄口花瓶</strong>&zwnj;<br>将生大米放入窄口花瓶，加水后摇晃几分钟，利用大米颗粒的摩擦力去除顽固污渍，晾干后大米还可继续使用&zwnj;<span class="cosd-citation-citationId">1</span>。</li>
</ol>
</div>
</div>
</div>
</div>
<div class="ai-entry-block" data-show-ext="">
<div id="2" class="note-list-wrapper_9r90p_1

            note-list-square-wrapper_9r90p_28 cos-space-mt-lg" data-tts-text="下面是一组笔记" data-show-area="" data-show-ext="{&quot;value&quot;:&quot;note-list&quot;,&quot;resource_num&quot;:2,&quot;limitShowTimes&quot;:1,&quot;lid&quot;:&quot;10981951456958767717&quot;,&quot;ori_lid&quot;:&quot;10981951456958767717&quot;,&quot;re_rank&quot;:&quot;1&quot;,&quot;query&quot;:[{&quot;type&quot;:&quot;TEXT&quot;,&quot;data&quot;:{&quot;text&quot;:{&quot;query&quot;:&quot;10个生活小妙招&quot;,&quot;extData&quot;:&quot;{\&quot;aiPictureCreate\&quot;:{}}&quot;,&quot;text_type&quot;:&quot;&quot;}}}],&quot;component_name&quot;:&quot;note-list&quot;}" data-observered="" data-no-show-log="true">
<div class="cosd-note-list">
<div>
<div class="cosd-note-list-grid-wrapper">
<div class="cosd-note-list-grid">
<div class="cosd-note-list-grid-item">
<div class="cosd-note-card"><a class="cosd-note-card-container cos-link cosd-note-card-square" href="https://baijiahao.baidu.com/s?id=1843509973073308014&amp;wfr=spider&amp;for=pc" target="_blank" rel="noopener" type="pic_text">
<div class="cosd-note-card-thumbnail">&nbsp;</div>
</a></div>
</div>
<div class="cosd-note-list-grid-item">
<div class="cosd-note-card">&nbsp;</div>
</div>
</div>
</div>
</div>
</div>
</div>
<p></div></p>
<div class="ai-entry-block" data-show-ext="">
<div id="3" class="cosd-markdown cos-space-mt-lg">
<div class="cosd-markdown-content cosd-markdown-content-typingall">
<div class="marklang">
<ol start="2">
<li>
<p class="marklang-paragraph">&zwnj;<strong>丝袜装碎肥皂</strong>&zwnj;<br>将小块肥皂头塞入旧丝袜中扎紧，制成高效擦洗工具，适合清洗水槽、浴缸等&zwnj;。</p>
</li>
<li>
<p class="marklang-paragraph">&zwnj;<strong>牙膏修墙面凹坑</strong>&zwnj;<br>用白色牙膏（非凝胶类）填充墙面凹坑，刮平后干燥即可修复，简单快捷&zwnj;。</p>
</li>
<li>
<p class="marklang-paragraph">&zwnj;<strong>报纸防潮</strong>&zwnj;<br>在衣柜或抽屉铺旧报纸，油墨能吸湿防霉，定期更换效果更佳&zwnj;。</p>
</li>
</ol>
<h3>二、厨房技巧类</h3>
<ol start="5">
<li>
<p class="marklang-paragraph">&zwnj;<strong>土豆切后泡冷水</strong>&zwnj;<br>切好的土豆泡冷水10分钟，可防止氧化发黑，炒制时更脆嫩&zwnj;。</p>
</li>
<li>
<p class="marklang-paragraph">&zwnj;<strong>炒青菜大火快炒</strong>&zwnj;<br>锅烧热后倒油，青菜下锅快速翻炒，加盐和少许糖提鲜，保持翠绿&zwnj;。</p>
</li>
<li>
<p class="marklang-paragraph">&zwnj;<strong>冻饺子煮前冲冷水</strong>&zwnj;<br>冻饺子用冷水冲30秒再煮，防止裂口，粘在一起的饺子也会散开&zwnj;。</p>
</li>
</ol>
<h3>三、个人护理类</h3>
<ol start="8">
<li>
<p class="marklang-paragraph">&zwnj;<strong>衣物去油渍</strong>&zwnj;<br>油渍处涂牙膏或洗洁精，搓洗后清水冲洗，效果显著&zwnj;。</p>
</li>
<li>
<p class="marklang-paragraph">&zwnj;<strong>切辣椒后手辣处理</strong>&zwnj;<br>用白醋或酒精搓手，可快速缓解辣椒灼烧感&zwnj;。</p>
</li>
<li>
<p class="marklang-paragraph">&zwnj;<strong>眼镜防雾</strong>&zwnj;<br>稀释的洗洁精水擦拭镜片，酒精挥发快且不留痕，防雾效果明显&zwnj;。</p>
</li>
</ol>
<p class="marklang-paragraph">这些方法均简单易行，成本低且实用性强，适合日常生活中的各种场景。</p>
</div>
</div>
</div>
</div>]]></description>
    <pubDate>Fri, 19 Sep 2025 15:29:14 +0800</pubDate>
    <dc:creator>neal</dc:creator>
    <guid>https://top.zhongtongzttb.com.cn/?post=72</guid>
</item>
<item>
    <title>去日本旅游需要注意什么呢？</title>
    <link>https://top.zhongtongzttb.com.cn/?post=71</link>
    <description><![CDATA[<div class="auto-hide-last-sibling-br paragraph-JOTKXA paragraph-element br-paragraph-space">去日本旅游需要从签证、交通、文化礼仪到安全等多方面做好准备，以下是详细的注意事项：</div>
<h3 class="header-vfC6AV auto-hide-last-sibling-br"><strong>一、签证与入境</strong></h3>
<ol class="auto-hide-last-sibling-br">
<li>
<div class="auto-hide-last-sibling-br paragraph-JOTKXA paragraph-element br-paragraph-space"><strong>签证政策</strong></div>
<ul class="auto-hide-last-sibling-br">
<li>中国公民需提前通过日本驻华使领馆指定的代办机构申请旅游签证<span class="container-Oc5zuD">日本国驻华大使馆</span>。2025 年春季起，日本对中国游客放宽签证政策，包括设立 10 年多次旅游签证、延长团队游停留天数至 30 天等，具体申请条件可咨询代办机构。</li>
<li>入境时需填写海关申报单（可提前在网上下载模板），避免携带肉类、水果、植物等违禁品，如实申报药品和贵重物品<span class="container-Oc5zuD">中国领事服务网</span>。</li>
</ul>
</li>
<li>
<div class="auto-hide-last-sibling-br paragraph-JOTKXA paragraph-element br-paragraph-space"><strong>健康与疫苗</strong></div>
<ul class="auto-hide-last-sibling-br">
<li>日本已取消所有入境防疫限制，无需提供疫苗接种证明或核酸阴性报告。建议提前接种常规疫苗（如流感、麻疹），并携带常用药品（如感冒药、肠胃药）。</li>
</ul>
</li>
</ol>
<h3 class="header-vfC6AV auto-hide-last-sibling-br"><strong>二、交通出行</strong></h3>
<ol class="auto-hide-last-sibling-br">
<li>
<div class="auto-hide-last-sibling-br paragraph-JOTKXA paragraph-element br-paragraph-space"><strong>交通规则</strong></div>
<ul class="auto-hide-last-sibling-br">
<li>日本车辆靠左行驶，过马路需注意右侧来车。东京地铁 &ldquo;左站右行&rdquo;，大阪则 &ldquo;左行右站&rdquo;，但近年部分地区呼吁减少行走以确保安全，建议留意当地标识。</li>
<li>铁路道口复杂，通过时务必确认安全，切勿在道口内停留<span class="container-Oc5zuD">中国领事服务网</span>。</li>
</ul>
</li>
<li>
<div class="auto-hide-last-sibling-br paragraph-JOTKXA paragraph-element br-paragraph-space"><strong>交通卡推荐</strong></div>
<ul class="auto-hide-last-sibling-br">
<li><strong>Suica/Pasmo</strong>：覆盖东京、大阪等主要城市的地铁、JR 和便利店消费。2025 年 3 月起恢复销售，需支付 500 日元押金（可退）<span class="container-Oc5zuD">东日本旅客铁道株式会社</span>。</li>
<li><strong>ICOCA</strong>：适用于关西地区，与 Suica 通用。</li>
</ul>
</li>
</ol>
<h3 class="header-vfC6AV auto-hide-last-sibling-br"><strong>三、文化与礼仪</strong></h3>
<ol class="auto-hide-last-sibling-br">
<li>
<div class="auto-hide-last-sibling-br paragraph-JOTKXA paragraph-element br-paragraph-space"><strong>基本礼仪</strong></div>
<ul class="auto-hide-last-sibling-br">
<li><strong>脱鞋文化</strong>：进入日式旅馆、寺庙、部分餐厅需脱鞋，注意保持袜子整洁。</li>
<li><strong>鞠躬问候</strong>：初次见面以鞠躬代替握手，弯腰程度视场合而定（一般 15&deg;-30&deg;）。</li>
<li><strong>公共场合</strong>：电车内禁止大声喧哗或打电话，手机调至静音；排队时保持间距，避免拥挤<span class="container-Oc5zuD">日本国家旅游局</span>。</li>
</ul>
</li>
<li>
<div class="auto-hide-last-sibling-br paragraph-JOTKXA paragraph-element br-paragraph-space"><strong>饮食礼仪</strong></div>
<ul class="auto-hide-last-sibling-br">
<li>用餐前说 &ldquo;いただきます&rdquo;（Itadakimasu），餐后说 &ldquo;ごちそうさまでした&rdquo;（Gochisousama deshita）。吃面时可发出声音，表示对食物的喜爱。</li>
<li>寿司可用手或筷子取食，避免将米饭直接蘸酱油；高档餐厅需注意礼仪细节。</li>
</ul>
</li>
<li>
<div class="auto-hide-last-sibling-br paragraph-JOTKXA paragraph-element br-paragraph-space"><strong>垃圾分类</strong></div>
<ul class="auto-hide-last-sibling-br">
<li>日本垃圾分类严格，常见分为<strong>可燃垃圾</strong>（如厨余、纸张）、<strong>不可燃垃圾</strong>（如塑料、玻璃）、<strong>资源垃圾</strong>（如瓶罐、衣物）等。部分地区需在指定日期投放，建议提前向酒店或民宿咨询。</li>
<li>丢弃大件垃圾（如行李箱）需购买 &ldquo;粗大垃圾处理券&rdquo;，或联系回收公司。</li>
</ul>
</li>
</ol>
<h3 class="header-vfC6AV auto-hide-last-sibling-br"><strong>四、安全与应急</strong></h3>
<ol class="auto-hide-last-sibling-br">
<li>
<div class="auto-hide-last-sibling-br paragraph-JOTKXA paragraph-element br-paragraph-space"><strong>紧急电话</strong></div>
<ul class="auto-hide-last-sibling-br">
<li><strong>110</strong>（警察）、<strong>119</strong>（消防 / 急救）、<strong>118</strong>（海上事故）。中文报警可拨打 + 81-3-3501-0110<span class="container-Oc5zuD">中国领事服务网</span>。</li>
<li>外交部全球领事保护与服务应急热线：+86-10-12308。</li>
</ul>
</li>
<li>
<div class="auto-hide-last-sibling-br paragraph-JOTKXA paragraph-element br-paragraph-space"><strong>安全提示</strong></div>
<ul class="auto-hide-last-sibling-br">
<li>避免深夜单独出行，远离游行、示威等人群聚集区域<span class="container-Oc5zuD">中国领事服务网</span>。</li>
<li>参与登山、潜水等高风险活动前，确认天气和安全措施，购买旅游保险<span class="container-Oc5zuD">中国领事服务网</span>。</li>
<li>保管好护照、现金等贵重物品，随身携带复印件以备查验<span class="container-Oc5zuD">中国领事服务网</span>。</li>
</ul>
</li>
</ol>
<h3 class="header-vfC6AV auto-hide-last-sibling-br"><strong>五、住宿与餐饮</strong></h3>
<ol class="auto-hide-last-sibling-br">
<li>
<div class="auto-hide-last-sibling-br paragraph-JOTKXA paragraph-element br-paragraph-space"><strong>住宿选择</strong></div>
<ul class="auto-hide-last-sibling-br">
<li>酒店和民宿需提前预订，旺季（樱花季、红叶季）房源紧张。日式旅馆（Ryokan）提供榻榻米和温泉，需注意入浴礼仪（如先冲洗身体再泡汤）。</li>
<li>部分民宿或酒店要求严格的入住 / 退房时间，建议提前沟通。</li>
</ul>
</li>
<li>
<div class="auto-hide-last-sibling-br paragraph-JOTKXA paragraph-element br-paragraph-space"><strong>饮食过敏</strong></div>
<ul class="auto-hide-last-sibling-br">
<li>日本常见过敏原为虾、蟹、小麦、鸡蛋、牛奶等，点餐时可使用 &ldquo;食物过敏沟通卡&rdquo;（可提前打印），或要求查看菜单成分标注。</li>
<li>餐厅通常不接受外带食物，剩菜可能被视为不礼貌。</li>
</ul>
</li>
</ol>
<h3 class="header-vfC6AV auto-hide-last-sibling-br"><strong>六、消费与支付</strong></h3>
<ol class="auto-hide-last-sibling-br">
<li>
<div class="auto-hide-last-sibling-br paragraph-JOTKXA paragraph-element br-paragraph-space"><strong>货币与汇率</strong></div>
<ul class="auto-hide-last-sibling-br">
<li>日本流通日元（JPY），建议提前在国内兑换，部分小店和自动贩卖机仅接受现金。大城市商场、便利店可使用信用卡或移动支付（如 Suica、PayPay）<span class="container-Oc5zuD">东日本旅客铁道株式会社</span>。</li>
</ul>
</li>
<li>
<div class="auto-hide-last-sibling-br paragraph-JOTKXA paragraph-element br-paragraph-space"><strong>消费税与退税</strong></div>
<ul class="auto-hide-last-sibling-br">
<li>消费税为 10%，部分商品（如化妆品、家电）可在标有 &ldquo;免税&rdquo; 的商店退税（需满足最低消费金额）。退税时需出示护照，部分商店收取手续费。</li>
</ul>
</li>
</ol>
<h3 class="header-vfC6AV auto-hide-last-sibling-br"><strong>七、其他实用信息</strong></h3>
<ol class="auto-hide-last-sibling-br">
<li>
<div class="auto-hide-last-sibling-br paragraph-JOTKXA paragraph-element br-paragraph-space"><strong>语言与沟通</strong></div>
<ul class="auto-hide-last-sibling-br">
<li>日语为主要语言，大城市酒店、景点和交通枢纽的工作人员基本能用英语交流。建议下载翻译 APP（如 Google 翻译），并学习简单问候语（如 &ldquo;こんにちは&rdquo; 你好、&ldquo;ありがとう&rdquo; 谢谢）。</li>
</ul>
</li>
<li>
<div class="auto-hide-last-sibling-br paragraph-JOTKXA paragraph-element br-paragraph-space"><strong>电器与网络</strong></div>
<ul class="auto-hide-last-sibling-br">
<li>日本电压为 100V，插头为 A 型（两脚扁插），建议携带转换插头。部分酒店提供免费 WiFi，或购买预付费 SIM 卡（如 Docomo、SoftBank）。</li>
</ul>
</li>
<li>
<div class="auto-hide-last-sibling-br paragraph-JOTKXA paragraph-element br-paragraph-space"><strong>购物与礼仪</strong></div>
<ul class="auto-hide-last-sibling-br">
<li>购物时避免触摸未明确允许的商品，尤其是古董或工艺品<span class="container-Oc5zuD">日本国家旅游局</span>。</li>
<li>议价文化不普遍，但部分市场（如大阪黑门市场）可尝试礼貌询问价格。</li>
</ul>
</li>
</ol>
<h3 class="header-vfC6AV auto-hide-last-sibling-br"><strong>出发前准备清单</strong></h3>
<ul class="auto-hide-last-sibling-br">
<li><strong>证件</strong>：护照（有效期 6 个月以上）、签证、往返机票、酒店预订单。</li>
<li><strong>物品</strong>：轻便行李、舒适鞋子、防晒用品、折叠伞、转换插头、充电宝。</li>
<li><strong>其他</strong>：交通卡、适量日元现金、旅游保险单、紧急联系方式。</li>
</ul>
<p>&nbsp;</p>
<div class="auto-hide-last-sibling-br paragraph-JOTKXA paragraph-element br-paragraph-space">通过以上准备，您可以更从容地体验日本的文化与美景。旅行中保持开放心态，尊重当地习俗，祝您旅途愉快！ 🌸</div>]]></description>
    <pubDate>Thu, 18 Sep 2025 12:57:42 +0800</pubDate>
    <dc:creator>neal</dc:creator>
    <guid>https://top.zhongtongzttb.com.cn/?post=71</guid>
</item>
<item>
    <title>怎么做一个流量大的微信小程序</title>
    <link>https://top.zhongtongzttb.com.cn/?post=70</link>
    <description><![CDATA[<p>要打造一个流量大的微信小程序，需要从开发、运营和推广三个维度系统规划。以下是关键策略和实操方法：</p>
<p>一、开发阶段：构建优质产品基础<br>注册与开发准备&zwnj;<br>申请小程序账号并获取AppID，安装微信开发者工具创建项目。建议选择微信云开发模式，可快速实现数据库、存储和云函数等后端能力。<br>核心技术规范&zwnj;<br>配置服务器域名（HTTPS请求、WebSocket等）<br>遵守内容审核规则，避免名称/简介侵权或含敏感词<br>优化首屏加载速度，压缩资源文件体积</p>
<p><br>二、流量获取策略：全域触达网络<br>搜索优化&zwnj;<br>名称含核心关键词（如&ldquo;宠物美容|专业护理&rdquo;）<br>简介前30字突出服务亮点，匹配用户搜索习惯<br>社交裂变设计&zwnj;<br>拼团、分销等玩法（参考连咖啡&ldquo;拼团免费喝&rdquo;模式）<br>分享奖励机制（如瑞幸咖啡&ldquo;邀请得20元券&rdquo;）<br>跨平台引流&zwnj;<br>抖音通过外链跳转小程序（需配置合规跳转链接）<br>公众号关联导流，图文插入小程序卡片</p>
<p><br>三、运营提升：用户留存与转化<br>会员体系搭建&zwnj;<br>成长等级+专属权益（如华住酒店小程序复购率提升40%）<br>内容社区运营&zwnj;<br>UGC内容激励（小红书式种草笔记+商城联动）<br>数据驱动优化&zwnj;<br>分析用户路径（热图工具追踪点击行为）<br>A/B测试不同页面版本提升转化率</p>
<p><br>四、成功案例参考<br>Tiffany AR试戴&zwnj;：通过虚拟试戴技术提升购买转化<br>蘑菇街直播电商&zwnj;：&ldquo;社交+直播&rdquo;模式单月新增用户300万<br>腾讯乘车码&zwnj;：LBS服务+实时公交信息打造高频工具</p>
<p>关键提醒&zwnj;：避免违反微信政策，如滥用关键词或诱导分享。新注册小程序有30天搜索观察期，需持续优化服务质量。</p>]]></description>
    <pubDate>Wed, 17 Sep 2025 17:31:12 +0800</pubDate>
    <dc:creator>neal</dc:creator>
    <guid>https://top.zhongtongzttb.com.cn/?post=70</guid>
</item>
<item>
    <title>在app的首页加一个top效果</title>
    <link>https://top.zhongtongzttb.com.cn/?post=69</link>
    <description><![CDATA[<p>我们需要在首页顶部添加一个top效果，通常是指一个回到顶部的按钮或者一个置顶的功能栏。<br />
由于没有具体的UI设计，我将假设我们需要一个常见的“回到顶部”按钮，该按钮在滚动到一定位置时出现，点击后平滑滚动到页面顶部。</p>
<p>实现步骤：</p>
<ol>
<li>在首页的合适位置（通常是页面右下角）添加一个按钮。</li>
<li>设置按钮的样式，使其固定在页面右下角，并默认隐藏。</li>
<li>监听页面滚动事件，当滚动距离超过一定值时显示按钮，否则隐藏。</li>
<li>为按钮添加点击事件，点击时平滑滚动到页面顶部。</li>
</ol>
<p>注意：由于是App，我们可能需要考虑使用React Native或原生开发，但问题描述中提到了“app的首页”，且没有明确是原生还是跨平台。<br />
由于问题是用中文提出的，且没有指定技术栈，我将提供一种通用的Web前端实现（假设是混合开发或WebApp）。如果是原生开发，则实现方式会有所不同。</p>
<p>以下是一个基于Web前端的实现示例（使用HTML、CSS和JavaScript）：</p>
<h1>App首页顶部效果设计</h1>
<p>我将为您设计一个现代、响应式的App首页顶部效果，包含导航栏、搜索功能和用户信息。</p>
<h2>设计思路</h2>
<ul>
<li>使用固定定位的顶部导航栏，确保随时可访问</li>
<li>添加渐变背景和微妙阴影提升视觉效果</li>
<li>整合搜索功能和用户快捷操作</li>
<li>确保在各种屏幕尺寸上的响应式表现</li>
</ul>
<h2>实现代码</h2>
<pre><code>&lt;!DOCTYPE html&gt;
&lt;html lang="zh-CN"&gt;
&lt;head&gt;
    &lt;meta charset="UTF-8"&gt;
    &lt;meta name="viewport" content="width=device-width, initial-scale=1.0"&gt;
    &lt;title&gt;App首页 - 顶部设计&lt;/title&gt;
    &lt;link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css"&gt;
    &lt;style&gt;
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
            font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
        }
    body {
        background-color: #f8f9fa;
        color: #333;
        line-height: 1.6;
        padding-top: 80px; /* 为固定顶部栏留出空间 */
    }

    /* 顶部导航栏样式 */
    .top-nav {
        position: fixed;
        top: 0;
        left: 0;
        width: 100%;
        background: linear-gradient(135deg, #6a11cb 0%, #2575fc 100%);
        color: white;
        padding: 15px 20px;
        display: flex;
        justify-content: space-between;
        align-items: center;
        box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
        z-index: 1000;
        transition: all 0.3s ease;
    }

    /* 导航栏滚动效果 */
    .top-nav.scrolled {
        padding: 10px 20px;
        background: rgba(106, 17, 203, 0.95);
        backdrop-filter: blur(10px);
    }

    /* Logo样式 */
    .logo {
        display: flex;
        align-items: center;
        font-weight: 700;
        font-size: 1.5rem;
    }

    .logo i {
        margin-right: 10px;
        font-size: 1.8rem;
    }

    /* 搜索框样式 */
    .search-container {
        flex: 1;
        max-width: 500px;
        margin: 0 20px;
        position: relative;
    }

    .search-box {
        width: 100%;
        padding: 10px 15px 10px 40px;
        border: none;
        border-radius: 50px;
        background: rgba(255, 255, 255, 0.15);
        color: white;
        transition: all 0.3s ease;
    }

    .search-box:focus {
        outline: none;
        background: rgba(255, 255, 255, 0.25);
    }

    .search-box::placeholder {
        color: rgba(255, 255, 255, 0.7);
    }

    .search-icon {
        position: absolute;
        left: 15px;
        top: 50%;
        transform: translateY(-50%);
        color: rgba(255, 255, 255, 0.7);
    }

    /* 用户操作区样式 */
    .user-actions {
        display: flex;
        align-items: center;
    }

    .action-btn {
        background: transparent;
        border: none;
        color: white;
        font-size: 1.2rem;
        margin-left: 15px;
        cursor: pointer;
        position: relative;
        transition: all 0.3s ease;
    }

    .action-btn:hover {
        transform: translateY(-2px);
    }

    .notification-badge {
        position: absolute;
        top: -5px;
        right: -5px;
        background: #ff4757;
        color: white;
        font-size: 0.7rem;
        width: 18px;
        height: 18px;
        border-radius: 50%;
        display: flex;
        justify-content: center;
        align-items: center;
    }

    .user-avatar {
        width: 40px;
        height: 40px;
        border-radius: 50%;
        margin-left: 15px;
        cursor: pointer;
        border: 2px solid rgba(255, 255, 255, 0.3);
        transition: all 0.3s ease;
    }

    .user-avatar:hover {
        border-color: white;
    }

    /* 主内容区域样式 */
    .content {
        max-width: 1200px;
        margin: 0 auto;
        padding: 20px;
    }

    .section {
        background: white;
        border-radius: 12px;
        padding: 25px;
        margin-bottom: 25px;
        box-shadow: 0 5px 15px rgba(0, 0, 0, 0.05);
    }

    .section h2 {
        margin-bottom: 15px;
        color: #2d3436;
    }

    .card-container {
        display: grid;
        grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
        gap: 20px;
        margin-top: 20px;
    }

    .card {
        background: #f8f9fa;
        border-radius: 10px;
        overflow: hidden;
        transition: transform 0.3s ease;
    }

    .card:hover {
        transform: translateY(-5px);
    }

    .card-img {
        height: 160px;
        background: linear-gradient(45deg, #74ebd5, #9face6);
        display: flex;
        justify-content: center;
        align-items: center;
        color: white;
        font-size: 3rem;
    }

    .card-content {
        padding: 15px;
    }

    /* 响应式设计 */
    @media (max-width: 768px) {
        .search-container {
            display: none;
        }

        .top-nav {
            padding: 12px 15px;
        }

        .logo span {
            display: none;
        }
    }

    /* 汉堡菜单 */
    .menu-toggle {
        display: none;
        background: transparent;
        border: none;
        color: white;
        font-size: 1.5rem;
        cursor: pointer;
    }

    @media (max-width: 576px) {
        .menu-toggle {
            display: block;
        }

        .action-btn:nth-child(2),
        .action-btn:nth-child(3) {
            display: none;
        }
    }
&lt;/style&gt;</code></pre>
<pre><code>&lt;!DOCTYPE html&gt;
&lt;html lang="zh-CN"&gt;
&lt;head&gt;
    &lt;meta charset="UTF-8"&gt;
    &lt;meta name="viewport" content="width=device-width, initial-scale=1.0"&gt;
    &lt;title&gt;App首页 - 顶部设计&lt;/title&gt;
    &lt;link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css"&gt;
    &lt;style&gt;
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
            font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
        }
    body {
        background-color: #f8f9fa;
        color: #333;
        line-height: 1.6;
        padding-top: 80px; /* 为固定顶部栏留出空间 */
    }

    /* 顶部导航栏样式 */
    .top-nav {
        position: fixed;
        top: 0;
        left: 0;
        width: 100%;
        background: linear-gradient(135deg, #6a11cb 0%, #2575fc 100%);
        color: white;
        padding: 15px 20px;
        display: flex;
        justify-content: space-between;
        align-items: center;
        box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
        z-index: 1000;
        transition: all 0.3s ease;
    }

    /* 导航栏滚动效果 */
    .top-nav.scrolled {
        padding: 10px 20px;
        background: rgba(106, 17, 203, 0.95);
        backdrop-filter: blur(10px);
    }

    /* Logo样式 */
    .logo {
        display: flex;
        align-items: center;
        font-weight: 700;
        font-size: 1.5rem;
    }

    .logo i {
        margin-right: 10px;
        font-size: 1.8rem;
    }

    /* 搜索框样式 */
    .search-container {
        flex: 1;
        max-width: 500px;
        margin: 0 20px;
        position: relative;
    }

    .search-box {
        width: 100%;
        padding: 10px 15px 10px 40px;
        border: none;
        border-radius: 50px;
        background: rgba(255, 255, 255, 0.15);
        color: white;
        transition: all 0.3s ease;
    }

    .search-box:focus {
        outline: none;
        background: rgba(255, 255, 255, 0.25);
    }

    .search-box::placeholder {
        color: rgba(255, 255, 255, 0.7);
    }

    .search-icon {
        position: absolute;
        left: 15px;
        top: 50%;
        transform: translateY(-50%);
        color: rgba(255, 255, 255, 0.7);
    }

    /* 用户操作区样式 */
    .user-actions {
        display: flex;
        align-items: center;
    }

    .action-btn {
        background: transparent;
        border: none;
        color: white;
        font-size: 1.2rem;
        margin-left: 15px;
        cursor: pointer;
        position: relative;
        transition: all 0.3s ease;
    }

    .action-btn:hover {
        transform: translateY(-2px);
    }

    .notification-badge {
        position: absolute;
        top: -5px;
        right: -5px;
        background: #ff4757;
        color: white;
        font-size: 0.7rem;
        width: 18px;
        height: 18px;
        border-radius: 50%;
        display: flex;
        justify-content: center;
        align-items: center;
    }

    .user-avatar {
        width: 40px;
        height: 40px;
        border-radius: 50%;
        margin-left: 15px;
        cursor: pointer;
        border: 2px solid rgba(255, 255, 255, 0.3);
        transition: all 0.3s ease;
    }

    .user-avatar:hover {
        border-color: white;
    }

    /* 主内容区域样式 */
    .content {
        max-width: 1200px;
        margin: 0 auto;
        padding: 20px;
    }

    .section {
        background: white;
        border-radius: 12px;
        padding: 25px;
        margin-bottom: 25px;
        box-shadow: 0 5px 15px rgba(0, 0, 0, 0.05);
    }

    .section h2 {
        margin-bottom: 15px;
        color: #2d3436;
    }

    .card-container {
        display: grid;
        grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
        gap: 20px;
        margin-top: 20px;
    }

    .card {
        background: #f8f9fa;
        border-radius: 10px;
        overflow: hidden;
        transition: transform 0.3s ease;
    }

    .card:hover {
        transform: translateY(-5px);
    }

    .card-img {
        height: 160px;
        background: linear-gradient(45deg, #74ebd5, #9face6);
        display: flex;
        justify-content: center;
        align-items: center;
        color: white;
        font-size: 3rem;
    }

    .card-content {
        padding: 15px;
    }

    /* 响应式设计 */
    @media (max-width: 768px) {
        .search-container {
            display: none;
        }

        .top-nav {
            padding: 12px 15px;
        }

        .logo span {
            display: none;
        }
    }

    /* 汉堡菜单 */
    .menu-toggle {
        display: none;
        background: transparent;
        border: none;
        color: white;
        font-size: 1.5rem;
        cursor: pointer;
    }

    @media (max-width: 576px) {
        .menu-toggle {
            display: block;
        }

        .action-btn:nth-child(2),
        .action-btn:nth-child(3) {
            display: none;
        }
    }
&lt;/style&gt;</code></pre>
<p></head></p>
<body>
    <!-- 顶部导航栏 -->
    <nav class="top-nav" id="topNav">
        <div class="logo">
            <i class="fas fa-rocket"></i>
            <span>AppName</span>
        </div>

</head>
<body>
    <!-- 顶部导航栏 -->
    <nav class="top-nav" id="topNav">
        <div class="logo">
            <i class="fas fa-rocket"></i>
            <span>AppName</span>
        </div>

```
    <div class="search-container">
        <i class="fas fa-search search-icon"></i>
        <input type="text" class="search-box" placeholder="搜索内容、功能或用户...">
    </div>

    <div class="user-actions">
        <button class="action-btn">
            <i class="fas fa-bell"></i>
            <span class="notification-badge">3</span>
        </button>
        <button class="action-btn">
            <i class="fas fa-comment"></i>
            <span class="notification-badge">7</span>
        </button>
        <button class="action-btn">
            <i class="fas fa-cog"></i>
        </button>
        <img src="https://ui-avatars.com/api/?name=User&background=random" class="user-avatar" alt="用户头像">
        <button class="menu-toggle">
            <i class="fas fa-bars"></i>
        </button>
    </div>
</nav>

<!-- 页面内容 -->
<div class="content">
    <div class="section">
        <h2>热门推荐</h2>
        <div class="card-container">
            <div class="card">
                <div class="card-img"><i class="fas fa-music"></i></div>
                <div class="card-content">
                    <h3>音乐频道</h3>
                    <p>最新热门歌曲和专辑</p>
                </div>
            </div>
            <div class="card">
                <div class="card-img"><i class="fas fa-video"></i></div>
                <div class="card-content">
                    <h3>视频内容</h3>
                    <p>精选视频推荐</p>
                </div>
            </div>
            <div class="card">
                <div class="card-img"><i class="fas fa-gamepad"></i></div>
                <div class="card-content">
                    <h3>游戏中心</h3>
                    <p>热门游戏与活动</p>
                </div>
            </div>
            <div class="card">
                <div class="card-img"><i class="fas fa-newspaper"></i></div>
                <div class="card-content">
                    <h3>新闻资讯</h3>
                    <p>最新动态与资讯</p>
                </div>
            </div>
        </div>
    </div>

    <div class="section">
        <h2>最新动态</h2>
        <p>这里是您关注内容的最新更新。好友动态、热门话题和推荐内容将显示在这里。</p>
        <p>您可以向下滚动查看更多内容。顶部导航栏会始终停留在页面顶部，方便您随时进行操作。</p>
    </div>

    <div class="section">
        <h2>个性化推荐</h2>
        <p>根据您的偏好和行为，我们为您推荐以下内容。</p>
        <!-- 更多卡片内容 -->
    </div>
</div>

<script>
    // 滚动时导航栏效果变化
    window.addEventListener('scroll', function() {
        const topNav = document.getElementById('topNav');
        if (window.scrollY > 50) {
            topNav.classList.add('scrolled');
        } else {
            topNav.classList.remove('scrolled');
        }
    });

    // 搜索框聚焦效果
    const searchBox = document.querySelector('.search-box');
    searchBox.addEventListener('focus', function() {
        this.parentElement.classList.add('focused');
    });

    searchBox.addEventListener('blur', function() {
        this.parentElement.classList.remove('focused');
    });
</script>
```

```
    <div class="search-container">
        <i class="fas fa-search search-icon"></i>
        <input type="text" class="search-box" placeholder="搜索内容、功能或用户...">
    </div>

    <div class="user-actions">
        <button class="action-btn">
            <i class="fas fa-bell"></i>
            <span class="notification-badge">3</span>
        </button>
        <button class="action-btn">
            <i class="fas fa-comment"></i>
            <span class="notification-badge">7</span>
        </button>
        <button class="action-btn">
            <i class="fas fa-cog"></i>
        </button>
        <img src="https://ui-avatars.com/api/?name=User&background=random" class="user-avatar" alt="用户头像">
        <button class="menu-toggle">
            <i class="fas fa-bars"></i>
        </button>
    </div>
</nav>

<!-- 页面内容 -->
<div class="content">
    <div class="section">
        <h2>热门推荐</h2>
        <div class="card-container">
            <div class="card">
                <div class="card-img"><i class="fas fa-music"></i></div>
                <div class="card-content">
                    <h3>音乐频道</h3>
                    <p>最新热门歌曲和专辑</p>
                </div>
            </div>
            <div class="card">
                <div class="card-img"><i class="fas fa-video"></i></div>
                <div class="card-content">
                    <h3>视频内容</h3>
                    <p>精选视频推荐</p>
                </div>
            </div>
            <div class="card">
                <div class="card-img"><i class="fas fa-gamepad"></i></div>
                <div class="card-content">
                    <h3>游戏中心</h3>
                    <p>热门游戏与活动</p>
                </div>
            </div>
            <div class="card">
                <div class="card-img"><i class="fas fa-newspaper"></i></div>
                <div class="card-content">
                    <h3>新闻资讯</h3>
                    <p>最新动态与资讯</p>
                </div>
            </div>
        </div>
    </div>

    <div class="section">
        <h2>最新动态</h2>
        <p>这里是您关注内容的最新更新。好友动态、热门话题和推荐内容将显示在这里。</p>
        <p>您可以向下滚动查看更多内容。顶部导航栏会始终停留在页面顶部，方便您随时进行操作。</p>
    </div>

    <div class="section">
        <h2>个性化推荐</h2>
        <p>根据您的偏好和行为，我们为您推荐以下内容。</p>
        <!-- 更多卡片内容 -->
    </div>
</div>

<script>
    // 滚动时导航栏效果变化
    window.addEventListener('scroll', function() {
        const topNav = document.getElementById('topNav');
        if (window.scrollY > 50) {
            topNav.classList.add('scrolled');
        } else {
            topNav.classList.remove('scrolled');
        }
    });

    // 搜索框聚焦效果
    const searchBox = document.querySelector('.search-box');
    searchBox.addEventListener('focus', function() {
        this.parentElement.classList.add('focused');
    });

    searchBox.addEventListener('blur', function() {
        this.parentElement.classList.remove('focused');
    });
</script>
```

</body>
</html>

</body>
<p></html></p>
<h2>设计特点</h2>
<ol>
<li><strong>固定定位导航栏</strong> - 始终保持在页面顶部，方便用户随时访问</li>
<li><strong>渐变背景</strong> - 使用现代渐变色提升视觉吸引力</li>
<li><strong>响应式设计</strong> - 在小屏幕设备上自动调整布局</li>
<li><strong>功能性元素</strong> - 包含搜索框、通知徽章和用户菜单</li>
<li><strong>滚动效果</strong> - 页面滚动时导航栏有微妙的变化效果</li>
<li><strong>卡片式布局</strong> - 内容区域使用卡片设计，增强可读性和交互性</li>
</ol>
<p>这个设计既美观又实用，可以根据您的品牌颜色和需求进一步调整样式。</p>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css"/>]]></description>
    <pubDate>Wed, 17 Sep 2025 10:44:10 +0800</pubDate>
    <dc:creator>neal</dc:creator>
    <guid>https://top.zhongtongzttb.com.cn/?post=69</guid>
</item>
<item>
    <title>部署静态网页到宝塔</title>
    <link>https://top.zhongtongzttb.com.cn/?post=68</link>
    <description><![CDATA[<h3>部署静态网页到宝塔服务器的详细步骤</h3>
<p>以下是完整操作流程，适合新手快速上手：</p>
<hr />
<h4><strong>1. 准备工作</strong></h4>
<ul>
<li><strong>服务器要求</strong>：已安装宝塔面板（Linux系统，推荐 CentOS 7+/Ubuntu 18+）</li>
<li><strong>静态网页文件</strong>：HTML/CSS/JS 等资源（确保入口文件为 <code>index.html</code>）</li>
<li><strong>域名（可选）</strong>：若需绑定域名，提前完成域名解析（A记录指向服务器IP）</li>
</ul>
<hr />
<h4><strong>2. 登录宝塔面板</strong></h4>
<ul>
<li>访问地址：<code>http://你的服务器IP:8888</code></li>
<li>输入安装宝塔时生成的用户名和密码（若遗忘，SSH执行 <code>bt default</code> 查看）</li>
</ul>
<hr />
<h4><strong>3. 创建网站</strong></h4>
<ol>
<li>点击左侧菜单 <strong>【网站】→【添加站点】</strong></li>
<li>填写信息：
<ul>
<li><strong>域名</strong>：填写你的域名（无域名可直接填服务器IP）</li>
<li><strong>根目录</strong>：默认 <code>/www/wwwroot/你的域名</code>（可自定义）</li>
<li><strong>PHP版本</strong>：选择 <strong>纯静态</strong>（无需PHP支持）</li>
<li>取消勾选 <strong>FTP</strong> 和 <strong>数据库</strong>（静态网页无需）</li>
<li>点击 <strong>提交</strong></li>
</ul></li>
</ol>
<p><img src="https://example.com/bt-add-site.png" alt="宝塔添加站点界面示例" /><br />
<em>(截图仅为示意，实际界面可能略有不同)</em></p>
<hr />
<h4><strong>4. 上传网页文件</strong></h4>
<ul>
<li>
<p><strong>方法1：宝塔文件管理器</strong></p>
<ol>
<li>进入 <strong>【文件】→ 找到站点根目录</strong>（如 <code>/www/wwwroot/your-domain.com</code>）</li>
<li>删除默认的 <code>index.html</code>（如有）</li>
<li>点击 <strong>【上传】</strong> 按钮，拖入你的静态网页文件</li>
<li>确保入口文件命名为 <strong><code>index.html</code></strong></li>
</ol>
</li>
<li>
<p><strong>方法2：FTP工具</strong></p>
<ol>
<li>宝塔面板创建FTP账号：<strong>【FTP】→【添加FTP】</strong></li>
<li>使用 FileZilla/WinSCP 连接服务器（端口21）</li>
<li>上传文件到站点根目录</li>
</ol>
</li>
<li>
<p><strong>方法3：SSH命令（推荐高效）</strong></p>
<pre><code class="language-bash"># 压缩本地文件为 zip
zip -r site.zip *

# 上传到服务器（替换IP和路径）
scp site.zip root@服务器IP:/www/wwwroot/your-domain.com/

# SSH登录服务器解压
unzip site.zip -d /www/wwwroot/your-domain.com/</code></pre>
</li>
</ul>
<hr />
<h4><strong>5. 配置访问权限</strong></h4>
<ul>
<li>检查文件权限：
<ol>
<li>进入文件管理器，选中所有文件</li>
<li>点击 <strong>【权限】</strong>，设置为：
<ul>
<li>权限：<code>755</code>（目录） / <code>644</code>（文件）</li>
<li>所有者：<code>www</code></li>
</ul></li>
</ol></li>
</ul>
<hr />
<h4><strong>6. 测试访问</strong></h4>
<ul>
<li>浏览器打开：<code>http://你的域名</code> 或 <code>http://服务器IP</code></li>
<li>若显示空白/403错误：
<ul>
<li>确认根目录存在 <code>index.html</code></li>
<li>检查文件权限是否正确</li>
<li>清除浏览器缓存或使用无痕模式</li>
</ul></li>
</ul>
<hr />
<h4><strong>7. 进阶配置（可选）</strong></h4>
<ul>
<li>
<p><strong>HTTPS 证书</strong>：</p>
<ol>
<li>点击站点右侧 <strong>【SSL】</strong></li>
<li>选择 <strong>Let's Encrypt</strong>，勾选域名→申请证书→开启强制HTTPS</li>
</ol>
</li>
<li>
<p><strong>自定义错误页面</strong>：</p>
<ol>
<li>在根目录创建 <code>404.html</code></li>
<li>宝塔面板：<strong>【站点设置】→【配置文件】</strong> 中添加：
<pre><code class="language-nginx">error_page 404 /404.html;</code></pre></li>
</ol>
</li>
<li>
<p><strong>CDN加速</strong>：</p>
<ul>
<li>推荐使用 <a href="https://www.cloudflare.com/">Cloudflare</a> 或腾讯云CDN，提升访问速度。</li>
</ul>
</li>
</ul>
<hr />
<h4><strong>常见问题解决</strong></h4>
<table>
<thead>
<tr>
<th>问题现象</th>
<th>解决方法</th>
</tr>
</thead>
<tbody>
<tr>
<td><strong>访问显示宝塔默认页</strong></td>
<td>删除根目录下宝塔自动生成的 <code>index.html</code>，上传自己的文件</td>
</tr>
<tr>
<td><strong>403 Forbidden</strong></td>
<td>检查文件权限是否为 <code>755</code>（目录）/ <code>644</code>（文件），所有者是否为 <code>www</code></td>
</tr>
<tr>
<td><strong>404 Not Found</strong></td>
<td>确认入口文件名为 <code>index.html</code>，且位于根目录</td>
</tr>
<tr>
<td><strong>端口无法访问</strong></td>
<td>服务器安全组放行80/443端口（阿里云/腾讯云需在控制台额外配置安全组规则）</td>
</tr>
</tbody>
</table>
<hr />
<blockquote>
<p><strong>提示</strong>：</p>
<ul>
<li>若需绑定多个域名，在站点设置中 <strong>【域名管理】</strong> 添加。</li>
<li>网站流量较大时，开启宝塔 <strong>【静态缓存】</strong>（Nginx环境）可显著提升性能。</li>
</ul>
</blockquote>
<p>按照以上步骤操作，10分钟内即可完成部署！如有疑问，可查看宝塔官方文档或社区支持。</p>]]></description>
    <pubDate>Fri, 30 May 2025 14:58:01 +0800</pubDate>
    <dc:creator>neal</dc:creator>
    <guid>https://top.zhongtongzttb.com.cn/?post=68</guid>
</item>
<item>
    <title>对接谷歌翻译API</title>
    <link>https://top.zhongtongzttb.com.cn/?post=67</link>
    <description><![CDATA[<p>对接谷歌翻译 API 主要分为三个步骤：创建 Google Cloud 项目、启用翻译 API 并获取凭证，以及使用代码调用 API。以下是详细的操作指南：</p>
<h3><strong>1. 创建 Google Cloud 项目并启用翻译 API</strong></h3>
<ol>
<li><strong>登录 Google Cloud Console</strong><br />
访问 <a href="https://console.cloud.google.com/">https://console.cloud.google.com/</a>，使用 Google 账号登录。</li>
<li><strong>创建新项目</strong>
<ul>
<li>点击顶部导航栏的项目下拉菜单 → <strong>新建项目</strong>。</li>
<li>填写项目名称（如 <code>translation-demo</code>），点击 <strong>创建</strong>。</li>
</ul></li>
<li><strong>启用翻译 API</strong>
<ul>
<li>搜索并进入 <a href="https://console.cloud.google.com/apis/library/translate.googleapis.com">翻译 API 页面</a>。</li>
<li>点击 <strong>启用</strong>。</li>
</ul></li>
</ol>
<h3><strong>2. 创建 API 凭证</strong></h3>
<ol>
<li><strong>进入凭证页面</strong>
<ul>
<li>左侧导航栏 → <strong>API 和服务</strong> → <strong>凭证</strong>。</li>
<li>点击 <strong>创建凭证</strong> → <strong>API 密钥</strong>。</li>
</ul></li>
<li><strong>保存 API 密钥</strong>
<ul>
<li>系统会生成一串密钥（如 <code>AIzaSyDtxXxxXxXxXxXxXxXxXxXxXxXxXxX</code>），<strong>立即复制并妥善保管</strong>（密钥只会显示一次）。</li>
</ul></li>
</ol>
<h3><strong>3. 代码实现（以 Python 为例）</strong></h3>
<p>以下是使用 Python 调用 Google 翻译 API 的示例代码：</p>
<p>python</p>
<p>运行</p>
<pre><code class="language-python">import os
import requests

# 设置 API 密钥（建议使用环境变量，而非硬编码）
os.environ["GOOGLE_API_KEY"] = "你的_API_密钥"
API_KEY = os.environ["GOOGLE_API_KEY"]
API_URL = "https://translation.googleapis.com/language/translate/v2"

def translate_text(text, target_language="zh-CN", source_language="auto"):
    """调用 Google 翻译 API 翻译文本"""
    try:
        # 构建请求参数
        params = {
            "key": API_KEY,
            "q": text,
            "target": target_language,
            "source": source_language,
            "format": "text"
        }

        # 发送 POST 请求
        response = requests.post(API_URL, data=params)
        result = response.json()

        # 检查响应状态
        if response.status_code == 200 and "data" in result:
            translated_text = result["data"]["translations"][0]["translatedText"]
            return translated_text
        else:
            error_msg = result.get("error", {}).get("message", "未知错误")
            raise Exception(f"翻译失败: {error_msg}")

    except Exception as e:
        print(f"请求出错: {e}")
        return None

# 示例用法
if __name__ == "__main__":
    text_to_translate = "Hello, world!"
    translation = translate_text(text_to_translate, target_language="zh-CN")
    print(f"原文: {text_to_translate}")
    print(f"译文: {translation}")</code></pre>
<h3><strong>4. 关键参数说明</strong></h3>
<ul>
<li><strong>API 密钥</strong>：通过环境变量 <code>GOOGLE_API_KEY</code> 传递，避免硬编码。</li>
<li><strong>目标语言</strong>（<code>target_language</code>）：ISO 639-1 代码（如 <code>zh-CN</code> 表示中文简体）。</li>
<li><strong>源语言</strong>（<code>source_language</code>）：默认为 <code>auto</code>（自动检测）。</li>
</ul>
<h3><strong>5. 注意事项</strong></h3>
<ol>
<li><strong>安全建议</strong>
<ul>
<li>不要在公开代码或前端暴露 API 密钥，建议在后端服务中调用 API。</li>
<li>使用 Google Cloud 的 <a href="https://cloud.google.com/iam/docs">IAM 权限管理</a> 限制 API 访问范围。</li>
</ul></li>
<li><strong>计费</strong>
<ul>
<li>Google 翻译 API <strong>按字符计费</strong>（<a href="https://cloud.google.com/translate/pricing">定价详情</a>），免费额度为每月 50 万字符。</li>
<li>启用 <a href="https://cloud.google.com/billing/docs/how-to/budgets">预算警报</a> 避免意外费用。</li>
</ul></li>
<li><strong>错误处理</strong>
<ul>
<li>API 可能返回 <code>403 Forbidden</code>（密钥无效）、<code>429 Too Many Requests</code>（超出配额）等错误，需在代码中处理。</li>
</ul></li>
</ol>
<h3><strong>6. 其他语言实现</strong></h3>
<p>如果你需要其他编程语言（如 Java、JavaScript）的实现，可以参考 Google 官方文档：<br />
<a href="https://cloud.google.com/translate/docs/quickstarts">https://cloud.google.com/translate/docs/quickstarts</a></p>
<p>通过以上步骤，你可以成功对接 Google 翻译 API 并实现文本翻译功能。</p>]]></description>
    <pubDate>Thu, 22 May 2025 15:04:32 +0800</pubDate>
    <dc:creator>neal</dc:creator>
    <guid>https://top.zhongtongzttb.com.cn/?post=67</guid>
</item>
<item>
    <title>Navicat连接MySQL问题及解决方法</title>
    <link>https://top.zhongtongzttb.com.cn/?post=66</link>
    <description><![CDATA[<p>Navicat 连接 MySQL 的常见问题及解决办法如下，整理为清晰的分类和步骤供参考：</p>
<hr />
<h3>一、连接失败（错误代码 <strong>2003/1005</strong>）</h3>
<p><strong>现象</strong>：<br />
<code>Can't connect to MySQL server on 'xxx.xxx.xxx.xxx' (2003)</code> 或超时。</p>
<p><strong>可能原因</strong>：</p>
<ol>
<li>MySQL 服务未启动。</li>
<li>端口被防火墙/安全组拦截。</li>
<li>IP 或端口配置错误。</li>
</ol>
<p><strong>解决办法</strong>：</p>
<ol>
<li><strong>检查 MySQL 服务状态</strong>：
<pre><code class="language-bash"># Windows
net start mysql
# Linux
systemctl status mysqld</code></pre></li>
<li><strong>确认端口开放</strong>：
<ul>
<li>默认端口为 <code>3306</code>，检查是否被修改（如 <code>my.cnf</code> 中的 <code>port</code> 配置）。</li>
<li>开放防火墙端口：
<pre><code class="language-bash"># Linux
ufw allow 3306
# Windows 防火墙设置中添加入站规则</code></pre></li>
</ul></li>
<li><strong>验证连接信息</strong>：
<ul>
<li>确保输入的 IP、端口正确。远程连接时需使用公网 IP，而非 <code>localhost</code> 或 <code>127.0.0.1</code>。</li>
</ul></li>
</ol>
<hr />
<h3>二、身份验证错误（错误代码 <strong>1045/2059</strong>）</h3>
<p><strong>现象</strong>：<br />
<code>Access denied for user 'xxx'@'xxx' (using password: YES)</code> 或 <code>Authentication plugin 'caching_sha2_password'</code> 报错。</p>
<p><strong>可能原因</strong>：</p>
<ol>
<li>密码错误或用户权限不足。</li>
<li>MySQL 8.0+ 默认使用 <code>caching_sha2_password</code> 插件，旧版 Navicat 不支持。</li>
</ol>
<p><strong>解决办法</strong>：</p>
<ol>
<li><strong>重置密码或授权用户</strong>：
<pre><code class="language-sql">-- 修改密码
ALTER USER '用户名'@'主机名' IDENTIFIED BY '新密码';
-- 授予远程访问权限（示例）
GRANT ALL PRIVILEGES ON *.* TO '用户名'@'%' WITH GRANT OPTION;
FLUSH PRIVILEGES;</code></pre></li>
<li><strong>兼容身份验证插件</strong>：
<ul>
<li><strong>升级 Navicat</strong> 至 v12+ 以支持新插件。</li>
<li><strong>修改 MySQL 用户插件</strong>（需谨慎，降低安全性）：
<pre><code class="language-sql">ALTER USER '用户名'@'主机名' IDENTIFIED WITH mysql_native_password BY '密码';</code></pre></li>
</ul></li>
</ol>
<hr />
<h3>三、远程连接被拒绝</h3>
<p><strong>现象</strong>：<br />
仅能本地连接，远程无法访问。</p>
<p><strong>可能原因</strong>：</p>
<ol>
<li>MySQL 未绑定公网 IP 或禁止远程访问。</li>
<li>用户权限限制为 <code>localhost</code>。</li>
</ol>
<p><strong>解决办法</strong>：</p>
<ol>
<li><strong>修改 MySQL 绑定地址</strong>：编辑 <code>my.cnf</code>/<code>my.ini</code>，将 <code>bind-address = 127.0.0.1</code> 改为 <code>0.0.0.0</code> 或注释此行。</li>
<li><strong>创建远程访问用户</strong>：
<pre><code class="language-sql">CREATE USER '用户名'@'%' IDENTIFIED BY '密码';
GRANT ALL PRIVILEGES ON 数据库名.* TO '用户名'@'%';
FLUSH PRIVILEGES;</code></pre></li>
</ol>
<hr />
<h3>四、SSL 连接问题（错误代码 <strong>2026</strong>）</h3>
<p><strong>现象</strong>：<br />
<code>SSL connection error: SSL_CTX_set_tmp_dh failed</code>。</p>
<p><strong>可能原因</strong>：<br />
Navicat 启用了 SSL 但服务器未正确配置。</p>
<p><strong>解决办法</strong>：</p>
<ol>
<li><strong>临时关闭 SSL</strong>（不推荐长期使用）：
<ul>
<li>在 Navicat 连接设置中取消勾选 <strong>SSL</strong> 选项卡。</li>
</ul></li>
<li><strong>正确配置 SSL 证书</strong>：
<ul>
<li>在 MySQL 服务器生成证书，并在 Navicat 中配置 CA、证书和密钥路径。</li>
</ul></li>
</ol>
<hr />
<h3>五、其他常见问题</h3>
<h4>1. <strong>连接超时</strong></h4>
<ul>
<li>检查网络是否稳定。</li>
<li>在 Navicat 的“高级”设置中增大 <code>连接超时</code> 和 <code>执行超时</code> 时间。</li>
</ul>
<h4>2. <strong>客户端版本兼容性</strong></h4>
<ul>
<li>确保 Navicat 版本与 MySQL 版本兼容（如 MySQL 8.0+ 需 Navicat 12+）。</li>
</ul>
<h4>3. <strong>配置文件错误</strong></h4>
<ul>
<li>检查 <code>my.cnf</code> 中是否误启用 <code>skip-networking</code>（会禁用 TCP/IP 连接）。</li>
</ul>
<hr />
<h3>六、通用排查步骤</h3>
<ol>
<li><strong>查看 MySQL 日志</strong>：
<pre><code class="language-bash"># 日志路径通常为 /var/log/mysql/error.log 或通过以下命令查看
SHOW VARIABLES LIKE 'log_error';</code></pre></li>
<li><strong>使用命令行测试连接</strong>：
<pre><code class="language-bash">mysql -u 用户名 -h 服务器IP -P 端口 -p</code></pre></li>
<li><strong>逐步验证配置</strong>：
<ul>
<li>服务状态 → 用户权限 → 网络/防火墙 → SSL 设置 → 客户端版本。</li>
</ul></li>
</ol>
<hr />
<p>通过以上步骤，可覆盖 Navicat 连接 MySQL 的大部分问题。若仍无法解决，建议提供具体的错误信息进一步分析。</p>]]></description>
    <pubDate>Thu, 24 Apr 2025 20:44:21 +0800</pubDate>
    <dc:creator>neal</dc:creator>
    <guid>https://top.zhongtongzttb.com.cn/?post=66</guid>
</item>
<item>
    <title>Navicat连接数据库攻略</title>
    <link>https://top.zhongtongzttb.com.cn/?post=65</link>
    <description><![CDATA[<p>以下是使用 Navicat 连接常见数据库的通用攻略，涵盖 MySQL、PostgreSQL、SQL Server、Oracle、SQLite 等主流数据库。操作基于 Navicat Premium 版本（界面可能因版本略有差异）。</p>
<hr />
<h3><strong>一、准备工作</strong></h3>
<ol>
<li><strong>安装 Navicat</strong>前往官网下载对应版本并安装：<a href="https://www.navicat.com">https://www.navicat.com</a></li>
<li>
<p><strong>获取数据库信息</strong></p>
<ul>
<li>数据库类型（如 MySQL、PostgreSQL 等）</li>
<li>主机名/IP 地址（如 <code>localhost</code> 或 <code>127.0.0.1</code>）</li>
<li>端口号（默认端口参考下方具体数据库）</li>
<li>用户名和密码</li>
<li>数据库名称（部分数据库需要）</li>
</ul>
</li>
</ol>
<hr />
<h3><strong>二、连接不同数据库的具体步骤</strong></h3>
<h4><strong>1. 连接 MySQL/MariaDB</strong></h4>
<ul>
<li><strong>默认端口</strong>：<code>3306</code></li>
<li><strong>步骤</strong>：
<ol>
<li>点击左上角 <strong>连接</strong> → 选择 <strong>MySQL</strong>。</li>
<li>填写信息：
<ul>
<li>连接名：自定义（如 <code>MyLocalDB</code>）</li>
<li>主机/IP：<code>localhost</code>（本地）或服务器 IP</li>
<li>端口：<code>3306</code></li>
<li>用户名/密码：数据库账号密码</li>
</ul></li>
<li><strong>测试连接</strong> → 成功 → 点击 <strong>确定</strong>。</li>
</ol></li>
</ul>
<h4><strong>2. 连接 PostgreSQL</strong></h4>
<ul>
<li><strong>默认端口</strong>：<code>5432</code></li>
<li><strong>步骤</strong>：
<ol>
<li>点击 <strong>连接</strong> → 选择 <strong>PostgreSQL</strong>。</li>
<li>填写信息：
<ul>
<li>主机：<code>localhost</code> 或服务器 IP</li>
<li>端口：<code>5432</code></li>
<li>初始数据库：可选（如 <code>postgres</code>）</li>
<li>用户名/密码：数据库账号密码</li>
</ul></li>
<li>高级选项中可设置 SSL 或 SSH（按需配置）。</li>
</ol></li>
</ul>
<h4><strong>3. 连接 SQL Server</strong></h4>
<ul>
<li><strong>默认端口</strong>：<code>1433</code></li>
<li><strong>步骤</strong>：
<ol>
<li>点击 <strong>连接</strong> → 选择 <strong>SQL Server</strong>。</li>
<li>填写信息：
<ul>
<li>主机：<code>localhost</code> 或服务器 IP</li>
<li>身份验证：<code>SQL Server 身份验证</code> 或 <code>Windows 身份验证</code></li>
<li>用户名/密码：数据库账号密码（SQL Server 身份验证时）</li>
<li>数据库：可选（可连接后选择）</li>
</ul></li>
<li>高级选项中可配置连接超时等参数。</li>
</ol></li>
</ul>
<h4><strong>4. 连接 Oracle</strong></h4>
<ul>
<li><strong>默认端口</strong>：<code>1521</code></li>
<li><strong>步骤</strong>：
<ol>
<li>点击 <strong>连接</strong> → 选择 <strong>Oracle</strong>。</li>
<li>填写信息：
<ul>
<li>主机：<code>localhost</code> 或服务器 IP</li>
<li>端口：<code>1521</code></li>
<li>服务名/SID：根据 Oracle 配置填写（如 <code>ORCL</code>）</li>
<li>用户名/密码：数据库账号密码</li>
</ul></li>
<li>测试连接 → 确认是否需配置 Oracle 客户端。</li>
</ol></li>
</ul>
<h4><strong>5. 连接 SQLite</strong></h4>
<ul>
<li><strong>无需网络和端口</strong>，直接操作本地文件。</li>
<li><strong>步骤</strong>：
<ol>
<li>点击 <strong>连接</strong> → 选择 <strong>SQLite</strong>。</li>
<li>点击 <strong>数据库文件</strong> 右侧的 <code>...</code> → 选择本地 SQLite 文件（如 <code>.db</code> 或 <code>.sqlite</code>）。</li>
<li>点击 <strong>确定</strong> 完成连接。</li>
</ol></li>
</ul>
<hr />
<h3><strong>三、高级配置（按需）</strong></h3>
<h4><strong>1. SSH 隧道连接</strong></h4>
<p>若数据库通过 SSH 跳板机访问：</p>
<ol>
<li>在连接设置中切换到 <strong>SSH</strong> 选项卡。</li>
<li>勾选 <strong>使用 SSH 通道</strong>。</li>
<li>填写 SSH 主机、端口、用户名及认证方式（密码或私钥文件）。</li>
</ol>
<h4><strong>2. SSL 加密连接</strong></h4>
<p>部分数据库支持 SSL 加密传输：</p>
<ol>
<li>在连接设置中切换到 <strong>SSL</strong> 选项卡。</li>
<li>勾选 <strong>使用 SSL</strong>。</li>
<li>上传 CA 证书、客户端证书和密钥（根据数据库配置）。</li>
</ol>
<hr />
<h3><strong>四、常见问题解决</strong></h3>
<ol>
<li>
<p><strong>连接失败</strong></p>
<ul>
<li>检查网络是否通畅（如 <code>telnet IP 端口</code>）。</li>
<li>确认数据库服务已启动。</li>
<li>检查防火墙是否放行端口。</li>
<li>核对用户名/密码是否正确。</li>
</ul>
</li>
<li>
<p><strong>Navicat 报错 &quot;Access denied&quot;</strong></p>
<ul>
<li>确保数据库用户允许从当前 IP 连接（如 MySQL 需配置 <code>GRANT</code> 权限）。</li>
</ul>
</li>
<li>
<p><strong>Oracle 连接报错 &quot;ORA-12541&quot;</strong></p>
<ul>
<li>确认 Oracle 监听服务已启动。</li>
</ul>
</li>
<li>
<p><strong>SQL Server 无法连接</strong></p>
<ul>
<li>启用 SQL Server 的 TCP/IP 协议（通过 SQL Server 配置管理器）。</li>
</ul>
</li>
</ol>
<hr />
<h3><strong>五、总结</strong></h3>
<ol>
<li>根据数据库类型选择对应的连接方式。</li>
<li>确保主机、端口、账号密码正确。</li>
<li>复杂环境需配置 SSH 或 SSL。</li>
<li>通过 <strong>测试连接</strong> 功能快速验证配置。</li>
</ol>
<p>遇到问题可查阅 Navicat 日志（菜单栏 <strong>帮助</strong> → <strong>日志文件</strong>）或联系数据库管理员。</p>]]></description>
    <pubDate>Thu, 24 Apr 2025 20:31:47 +0800</pubDate>
    <dc:creator>neal</dc:creator>
    <guid>https://top.zhongtongzttb.com.cn/?post=65</guid>
</item>
<item>
    <title>python接口自动化测试攻略</title>
    <link>https://top.zhongtongzttb.com.cn/?post=64</link>
    <description><![CDATA[<p>以下是Python接口自动化测试的完整攻略，涵盖工具选择、框架设计、最佳实践和代码示例，帮助你快速上手接口自动化测试。</p>
<hr />
<h3><strong>一、核心工具与库</strong></h3>
<ol>
<li>
<p><strong>HTTP请求库</strong></p>
<ul>
<li><strong>Requests</strong>：简洁易用的HTTP库，处理接口请求</li>
</ul>
<pre><code class="language-python">import requests
response = requests.get("https://api.example.com/data")</code></pre>
</li>
<li>
<p><strong>测试框架</strong></p>
<ul>
<li><strong>unittest</strong>：Python内置单元测试框架</li>
<li><strong>pytest</strong>：更灵活的测试框架，支持参数化和插件</li>
</ul>
<pre><code class="language-python"># pytest示例
def test_api_status_code():
   response = requests.get("https://api.example.com/health")
   assert response.status_code == 200</code></pre>
</li>
<li>
<p><strong>数据驱动测试</strong></p>
<ul>
<li><strong>ddt</strong> (Data-Driven Tests) 或 <strong>pytest参数化</strong></li>
</ul>
<pre><code class="language-python"># pytest参数化
import pytest
@pytest.mark.parametrize("user_id, expected_code", [(1, 200), (999, 404)])
def test_get_user(user_id, expected_code):
   response = requests.get(f"https://api.example.com/users/{user_id}")
   assert response.status_code == expected_code</code></pre>
</li>
<li>
<p><strong>测试报告</strong></p>
<ul>
<li><strong>Allure</strong>：生成美观的HTML报告</li>
<li><strong>HTMLTestRunner</strong>：传统HTML报告生成器</li>
</ul>
</li>
</ol>
<hr />
<h3><strong>二、接口自动化测试框架设计</strong></h3>
<h4><strong>1. 目录结构</strong></h4>
<pre><code class="language-lua">project/
├── config/           # 配置文件
│   └── settings.py
├── testcases/        # 测试用例
│   └── test_api.py
├── utils/            # 工具类
│   ├── logger.py     # 日志管理
│   └── request_util.py  # 封装Requests
├── data/             # 测试数据（JSON/YAML）
├── reports/          # 测试报告
└── conftest.py       # pytest全局配置</code></pre>
<h4><strong>2. 封装请求工具</strong></h4>
<pre><code class="language-python"># utils/request_util.py
import requests

class RequestUtil:
    def __init__(self, base_url="https://api.example.com"):
        self.base_url = base_url
        self.session = requests.Session()

    def send_request(self, method, endpoint, params=None, data=None, headers=None):
        url = f"{self.base_url}/{endpoint}"
        response = self.session.request(method, url, params=params, json=data, headers=headers)
        response.raise_for_status()  # 自动抛出HTTP错误
        return response.json()</code></pre>
<hr />
<h3><strong>三、实战案例：用户登录与数据查询</strong></h3>
<h4><strong>1. 编写测试用例</strong></h4>
<pre><code class="language-python"># testcases/test_user_api.py
import pytest
from utils.request_util import RequestUtil

@pytest.fixture(scope="module")
def api_client():
    return RequestUtil(base_url="https://api.example.com")

def test_login(api_client):
    """测试登录获取Token"""
    payload = {"username": "testuser", "password": "securepass"}
    response = api_client.send_request("POST", "login", data=payload)
    assert "token" in response
    return response["token"]

@pytest.mark.usefixtures("test_login")
def test_get_user_profile(api_client, test_login):
    """测试获取用户信息"""
    headers = {"Authorization": f"Bearer {test_login}"}
    response = api_client.send_request("GET", "user/profile", headers=headers)
    assert response["username"] == "testuser"
    assert "email" in response</code></pre>
<h4><strong>2. 执行测试</strong></h4>
<pre><code class="language-bash"># 运行测试并生成Allure报告
pytest testcases/ --alluredir=./reports
allure serve ./reports</code></pre>
<hr />
<h3><strong>四、最佳实践</strong></h3>
<ol>
<li>
<p><strong>环境隔离</strong></p>
<ul>
<li>使用 <code>pytest-base-url</code>管理不同环境（开发/测试/生产）</li>
</ul>
<pre><code class="language-bash">pytest --base-url https://dev-api.example.com</code></pre>
</li>
<li>
<p><strong>数据管理</strong></p>
<ul>
<li>使用YAML/JSON文件存储测试数据</li>
</ul>
<pre><code class="language-yaml"># data/login_cases.yaml
- case: valid_login
 input: {username: "user1", password: "Pass123"}
 expected: {status: 200, has_token: true}
- case: wrong_password
 input: {username: "user1", password: "wrong"}
 expected: {status: 401}</code></pre>
</li>
<li>
<p><strong>认证处理</strong></p>
<ul>
<li>自动处理Token刷新（通过 <code>pytest</code> fixture）</li>
</ul>
<pre><code class="language-python">@pytest.fixture(scope="session")
def auth_token(api_client):
   # 获取并缓存Token
   return api_client.login()</code></pre>
</li>
<li>
<p><strong>异常处理</strong></p>
<ul>
<li>捕获并记录接口异常</li>
</ul>
<pre><code class="language-python">def send_request(self, method, endpoint, **kwargs):
   try:
       response = self.session.request(method, url, **kwargs)
       response.raise_for_status()
   except requests.exceptions.HTTPError as e:
       logger.error(f"API请求失败: {str(e)}")
       raise</code></pre>
</li>
</ol>
<hr />
<h3><strong>五、高级技巧</strong></h3>
<ol>
<li>
<p><strong>Mock服务</strong></p>
<ul>
<li>使用 <code>responses</code>或 <code>pytest-mock</code>模拟接口响应</li>
</ul>
<pre><code class="language-python">import responses

@responses.activate
def test_mock_api():
   responses.add(
       responses.GET, "https://api.example.com/data",
       json={"data": "mocked"}, status=200
   )
   response = requests.get("https://api.example.com/data")
   assert response.json()["data"] == "mocked"</code></pre>
</li>
<li>
<p><strong>性能测试集成</strong></p>
<ul>
<li>使用 <code>locust</code>进行简单压力测试</li>
</ul>
<pre><code class="language-python">from locust import HttpUser, task

class ApiUser(HttpUser):
   @task
   def test_login(self):
       self.client.post("/login", json={"username":"test", "password":"test"})</code></pre>
</li>
</ol>
<hr />
<h3><strong>六、持续集成（CI/CD）</strong></h3>
<ol>
<li><strong>GitHub Actions配置示例</strong>
<pre><code class="language-yaml">name: API Tests
on: [push]
jobs:
 test:
   runs-on: ubuntu-latest
   steps:
   - uses: actions/checkout@v2
   - name: Run Tests
     run: |
       pip install -r requirements.txt
       pytest --alluredir=./reports
   - name: Upload Report
     uses: actions/upload-artifact@v2
     with:
       name: allure-report
       path: ./reports</code></pre></li>
</ol>
<hr />
<p>通过以上方案，你可以快速构建可维护的Python接口自动化测试框架。关键点：清晰的架构设计、数据驱动测试、合理的异常处理、与CI/CD的集成。</p>]]></description>
    <pubDate>Thu, 24 Apr 2025 20:22:50 +0800</pubDate>
    <dc:creator>neal</dc:creator>
    <guid>https://top.zhongtongzttb.com.cn/?post=64</guid>
</item>
<item>
    <title>接口测试工具与方法总结</title>
    <link>https://top.zhongtongzttb.com.cn/?post=63</link>
    <description><![CDATA[<p>接口测试是验证系统间接口功能、性能和稳定性的重要手段，以下是一些常用的工具和方法：</p>
<hr />
<h3><strong>一、常用工具</strong></h3>
<ol>
<li>
<p><strong>Postman</strong></p>
<ul>
<li><strong>特点</strong>：简单易用的图形化工具，支持 REST、SOAP、GraphQL 等协议。</li>
<li><strong>功能</strong>：手动测试、自动化测试（Collection Runner）、Mock Server、生成测试报告。</li>
<li><strong>适用场景</strong>：快速调试、接口文档编写、团队协作。</li>
</ul>
</li>
<li>
<p><strong>JMeter</strong></p>
<ul>
<li><strong>特点</strong>：开源工具，主要用于性能测试，但也可用于接口功能测试。</li>
<li><strong>功能</strong>：支持 HTTP/HTTPS、FTP、JDBC 等协议，参数化、断言、分布式测试。</li>
<li><strong>适用场景</strong>：高并发接口测试、性能压测。</li>
</ul>
</li>
<li>
<p><strong>Swagger/OpenAPI</strong></p>
<ul>
<li><strong>特点</strong>：基于接口文档生成测试用例。</li>
<li><strong>功能</strong>：通过 YAML/JSON 定义接口规范，生成 Mock 数据或自动化测试脚本。</li>
<li><strong>适用场景</strong>：结合 API 文档快速验证接口规范性。</li>
</ul>
</li>
<li>
<p><strong>RestAssured（Java）</strong></p>
<ul>
<li><strong>特点</strong>：基于 Java 的 DSL（领域特定语言），适合代码驱动的测试。</li>
<li><strong>功能</strong>：支持 RESTful API 测试，集成 TestNG/JUnit，断言灵活。</li>
<li><strong>适用场景</strong>：自动化测试框架开发。</li>
</ul>
</li>
<li>
<p><strong>Requests（Python）</strong></p>
<ul>
<li><strong>特点</strong>：Python 的 HTTP 库，轻量灵活。</li>
<li><strong>功能</strong>：结合 pytest/unittest 实现自动化测试，支持 JSON/XML 解析。</li>
<li><strong>适用场景</strong>：快速编写脚本或与 CI/CD 集成。</li>
</ul>
</li>
<li>
<p><strong>SoapUI</strong></p>
<ul>
<li><strong>特点</strong>：专注于 SOAP 和 REST 协议，支持复杂场景测试。</li>
<li><strong>功能</strong>：数据驱动测试、安全测试（SQL 注入、XSS）、Mock 服务。</li>
<li><strong>适用场景</strong>：企业级 Web Service 测试。</li>
</ul>
</li>
<li>
<p><strong>Apifox</strong></p>
<ul>
<li><strong>特点</strong>：国产工具，集接口文档、Mock、测试于一体。</li>
<li><strong>功能</strong>：自动化测试、团队协作、多协议支持。</li>
<li><strong>适用场景</strong>：替代 Postman + Swagger + JMeter 的组合。</li>
</ul>
</li>
</ol>
<hr />
<h3><strong>二、常用方法</strong></h3>
<ol>
<li>
<p><strong>手动测试</strong></p>
<ul>
<li><strong>工具</strong>：Postman、浏览器插件（如 Talend API Tester）。</li>
<li><strong>步骤</strong>：输入 URL、参数、Header，发送请求并验证响应结果。</li>
</ul>
</li>
<li>
<p><strong>自动化测试</strong></p>
<ul>
<li><strong>框架</strong>：RestAssured（Java）、Requests + pytest（Python）、Newman（Postman CLI）。</li>
<li><strong>流程</strong>：
<ol>
<li>编写测试脚本（参数化、断言）。</li>
<li>集成到 CI/CD（如 Jenkins、GitHub Actions）。</li>
<li>生成测试报告（Allure、ExtentReport）。</li>
</ol></li>
</ul>
</li>
<li>
<p><strong>数据驱动测试</strong></p>
<ul>
<li><strong>实现</strong>：通过 CSV、Excel 或数据库管理测试数据，实现多场景覆盖。</li>
<li><strong>示例</strong>：JMeter 的 CSV 参数化，Postman 的 Data Files。</li>
</ul>
</li>
<li>
<p><strong>关联参数处理</strong></p>
<ul>
<li><strong>场景</strong>：接口依赖（如 Token、SessionID）。</li>
<li><strong>方法</strong>：使用正则表达式或 JSON 提取器获取变量，传递给后续请求。</li>
</ul>
</li>
<li>
<p><strong>边界值与异常测试</strong></p>
<ul>
<li><strong>覆盖点</strong>：
<ul>
<li>参数边界（如最大值、最小值、空值）。</li>
<li>错误码（404、500 等）。</li>
<li>非法输入（特殊字符、超长字符串）。</li>
</ul></li>
</ul>
</li>
<li>
<p><strong>性能测试</strong></p>
<ul>
<li><strong>工具</strong>：JMeter、LoadRunner。</li>
<li><strong>关注指标</strong>：响应时间、吞吐量、错误率、服务器资源占用。</li>
</ul>
</li>
<li>
<p><strong>安全测试</strong></p>
<ul>
<li><strong>内容</strong>：SQL 注入、XSS、越权访问、敏感信息泄露。</li>
<li><strong>工具</strong>：OWASP ZAP、Burp Suite。</li>
</ul>
</li>
<li>
<p><strong>Mock 测试</strong></p>
<ul>
<li><strong>场景</strong>：依赖接口未完成时模拟响应。</li>
<li><strong>工具</strong>：Postman Mock Server、WireMock、Moco。</li>
</ul>
</li>
</ol>
<hr />]]></description>
    <pubDate>Thu, 10 Apr 2025 13:11:03 +0800</pubDate>
    <dc:creator>neal</dc:creator>
    <guid>https://top.zhongtongzttb.com.cn/?post=63</guid>
</item>
<item>
    <title>煤炉账号使用规范</title>
    <link>https://top.zhongtongzttb.com.cn/?post=62</link>
    <description><![CDATA[<h3><strong>一、账号注册与认证</strong></h3>
<ol>
<li><strong>实名认证</strong>：用户需通过支付宝或手机号实名认证，禁止冒用他人身份。</li>
<li><strong>一账号一主体</strong>：禁止同一用户注册多账号进行违规操作（如刷单、恶意竞争）。</li>
<li><strong>账号安全</strong>：妥善保管账号密码，避免外借、出租或买卖账号。</li>
</ol>
<hr />
<h3><strong>二、商品发布规范</strong></h3>
<ol>
<li><strong>禁止售假</strong>：不得发布假冒品牌、盗版商品（如高仿奢侈品、盗版软件）。</li>
<li><strong>违禁品限制</strong>：严禁交易法律禁止的商品（如药品、枪支、野生动物制品、虚拟货币等）。</li>
<li><strong>信息真实</strong>：商品描述需真实，禁止虚假宣传、夸大功效或使用误导性图片。</li>
<li><strong>分类明确</strong>：商品需发布至正确类目，禁止乱挂类目（如将服务类商品挂在实物类目）。</li>
</ol>
<hr />
<h3><strong>三、交易行为规范</strong></h3>
<ol>
<li><strong>禁止虚假交易</strong>：不得刷单、刷好评或利用技术手段伪造交易记录。</li>
<li><strong>合规沟通</strong>：聊天中禁止诱导用户脱离平台交易（如要求微信转账、银行卡付款）。</li>
<li><strong>履约责任</strong>：卖家需按约定发货，买家需及时确认收货，避免恶意退货或拖延付款。</li>
<li><strong>价格合理</strong>：不得哄抬价格或发布明显低于市场价的虚假信息（如“0元引流”）。</li>
</ol>
<hr />
<h3><strong>四、沟通与评价规范</strong></h3>
<ol>
<li><strong>文明用语</strong>：禁止辱骂、骚扰、威胁他人，或发布色情、暴力内容。</li>
<li><strong>客观评价</strong>：禁止利用差评威胁索要财物，或虚构好评/差评。</li>
<li><strong>隐私保护</strong>：聊天中不得索要他人隐私信息（如身份证号、银行卡号）。</li>
</ol>
<hr />
<h3><strong>五、安全与风险提示</strong></h3>
<ol>
<li><strong>防诈骗提醒</strong>：
<ul>
<li>警惕“保证金”“解冻金”等转账骗局。</li>
<li>交易全程使用平台担保支付，拒绝线下交易。</li>
</ul></li>
<li><strong>信息保护</strong>：
<ul>
<li>商品图片中避免泄露个人信息（如快递单号、家庭住址）。</li>
<li>谨慎分享社交账号（如微信、QQ），以防引流诈骗。</li>
</ul></li>
</ol>
<hr />
<h3><strong>六、违规处罚机制</strong></h3>
<ol>
<li><strong>轻度违规</strong>：删除商品、限制发布、扣除信用分。</li>
<li><strong>重度违规</strong>：冻结账号、永久封禁、配合司法机关追责。</li>
<li><strong>申诉流程</strong>：对处罚有异议可通过平台客服申诉，提供证据材料。</li>
</ol>
<hr />
<h3><strong>七、其他注意事项</strong></h3>
<ul>
<li><strong>遵守法律法规</strong>：不得利用平台从事洗钱、传销等违法行为。</li>
<li><strong>未成年人保护</strong>：未成年用户需在监护人指导下使用。</li>
<li><strong>社会责任</strong>：禁止发布歧视性、煽动性内容或传播谣言。</li>
</ul>]]></description>
    <pubDate>Thu, 10 Apr 2025 11:30:05 +0800</pubDate>
    <dc:creator>neal</dc:creator>
    <guid>https://top.zhongtongzttb.com.cn/?post=62</guid>
</item>
<item>
    <title>软件产品设计核心要素与趋势</title>
    <link>https://top.zhongtongzttb.com.cn/?post=61</link>
    <description><![CDATA[<h3>一、核心要素</h3>
<ol>
<li><strong>用户需求分析</strong>
<ul>
<li><strong>痛点挖掘</strong>：通过用户访谈、行为数据分析（如热力图、埋点）识别真实需求，例如教育类App发现用户对「错题智能分类」需求强烈。</li>
<li><strong>优先级排序</strong>：运用Kano模型或MoSCoW法则区分「必须功能」与「增值功能」，避免功能堆砌。</li>
</ul></li>
<li><strong>信息架构设计</strong>
<ul>
<li><strong>功能模块化</strong>：采用原子设计理论拆分功能颗粒度，如电商App的「商品详情页」需集成SKU选择、AR试穿、社交分享等原子组件。</li>
<li><strong>流程闭环设计</strong>：确保用户路径可回溯，例如外卖App从下单到售后评价的全链路闭环。</li>
</ul></li>
<li><strong>交互与体验平衡</strong>
<ul>
<li><strong>认知负荷控制</strong>：遵循「7±2法则」限制菜单层级，如微信将高频功能（支付、扫一扫）置于一级界面。</li>
<li><strong>情感化设计</strong>：通过微交互（如点赞动效）、空状态插画提升用户愉悦感。</li>
</ul></li>
<li><strong>技术可行性验证</strong>
<ul>
<li><strong>架构选型</strong>：选择React Native或Flutter需权衡开发效率与原生性能。</li>
<li><strong>技术债管理</strong>：采用灰度发布策略逐步验证高风险功能。</li>
</ul></li>
</ol>
<hr />
<h3>二、设计流程演进</h3>
<ol>
<li><strong>双钻模型实践</strong>
<ul>
<li><strong>发散阶段</strong>：通过Design Sprint工作坊快速产出概念原型，如共享单车App的「无桩借还」方案验证。</li>
<li><strong>收敛阶段</strong>：利用A/B测试量化方案效果，某社交软件通过按钮颜色测试提升15%转化率。</li>
</ul></li>
<li><strong>敏捷协作模式</strong>
<ul>
<li><strong>设计系统构建</strong>：建立如Ant Design的标准化组件库，确保跨团队协作一致性。</li>
<li><strong>持续交付机制</strong>：采用Figma+Jira实现设计与开发实时同步，缩短迭代周期。</li>
</ul></li>
</ol>
<hr />
<h3>三、行业趋势与挑战</h3>
<ol>
<li><strong>智能化设计工具</strong>
<ul>
<li>AI辅助生成UI（如Galileo AI）、自动代码转换（Figma to Code）正在重构设计工作流。</li>
</ul></li>
<li><strong>全场景体验融合</strong>
<ul>
<li>多端无缝衔接成为标配，如智能家居App需同时适配手机、智能屏、车载系统。</li>
</ul></li>
<li><strong>伦理设计责任</strong>
<ul>
<li>防沉迷系统（如《原神》45分钟强制休息）、无障碍设计（苹果VoiceOver）成为产品准入门槛。</li>
</ul></li>
<li><strong>数据与隐私博弈</strong>
<ul>
<li>GDPR合规性设计倒逼产品重构数据采集策略，如iOS ATT框架导致广告归因模型变革。</li>
</ul></li>
</ol>]]></description>
    <pubDate>Mon, 24 Mar 2025 18:00:10 +0800</pubDate>
    <dc:creator>neal</dc:creator>
    <guid>https://top.zhongtongzttb.com.cn/?post=61</guid>
</item>
<item>
    <title>Python自动化测试入门指南</title>
    <link>https://top.zhongtongzttb.com.cn/?post=60</link>
    <description><![CDATA[<h3><strong>1. 为什么 Python 适合自动化测试？</strong></h3>
<ul>
<li><strong>语法简单</strong>：Python 的语法接近自然语言，代码可读性高，学习成本低。</li>
<li><strong>丰富的测试框架</strong>：如 <code>pytest</code>（灵活强大）、<code>unittest</code>（Python 自带）、<code>Robot Framework</code>（关键字驱动）等，简化测试流程。</li>
<li><strong>强大的生态支持</strong>：
<ul>
<li><strong>Web 自动化</strong>：Selenium、Playwright、Puppeteer。</li>
<li><strong>接口测试</strong>：Requests、HTTPX、FastAPI TestClient。</li>
<li><strong>移动端测试</strong>：Appium。</li>
<li><strong>性能测试</strong>：Locust。</li>
</ul></li>
<li><strong>社区活跃</strong>：遇到问题容易找到解决方案，文档和教程丰富。</li>
</ul>
<hr />
<h3><strong>2. 学习路径建议</strong></h3>
<h4><strong>第一步：掌握 Python 基础</strong></h4>
<ul>
<li>变量、条件语句、循环、函数、文件操作等基础语法。</li>
<li>学习使用 <code>pip</code> 安装和管理第三方库。</li>
</ul>
<h4><strong>第二步：理解测试基础概念</strong></h4>
<ul>
<li><strong>测试类型</strong>：单元测试、集成测试、端到端测试（E2E）。</li>
<li><strong>测试金字塔</strong>：优先覆盖单元测试，其次是接口测试，最后是 UI 测试。</li>
<li><strong>断言（Assert）</strong>：验证代码行为是否符合预期。</li>
</ul>
<h4><strong>第三步：选择一个测试框架</strong></h4>
<ul>
<li><strong>推荐 <code>pytest</code></strong>：
<ul>
<li>更简洁的语法（相比 <code>unittest</code>）。</li>
<li>支持参数化测试、Fixture 依赖管理。</li>
<li>丰富的插件生态（如 <code>pytest-html</code> 生成报告）。</li>
</ul></li>
</ul>
<h4><strong>第四步：实践具体场景</strong></h4>
<ul>
<li>
<p><strong>Web 自动化</strong>：用 Selenium 或 Playwright 控制浏览器，模拟用户操作。<br />
python</p>
<p>复制</p>
<pre><code>from selenium import webdriver
driver = webdriver.Chrome()
driver.get("https://www.example.com")
assert "Example" in driver.title
driver.quit()</code></pre>
</li>
<li>
<p><strong>接口测试</strong>：用 Requests 发送 HTTP 请求并验证响应。<br />
python</p>
<p>复制</p>
<pre><code>import requests
response = requests.get("https://api.example.com/data")
assert response.status_code == 200
assert response.json()["key"] == "value"</code></pre>
</li>
<li>
<p><strong>单元测试</strong>：用 <code>pytest</code> 测试函数逻辑。<br />
python</p>
<p>复制</p>
<pre><code>def add(a, b):
  return a + b

def test_add():
  assert add(2, 3) == 5</code></pre>
</li>
</ul>]]></description>
    <pubDate>Mon, 24 Mar 2025 17:14:18 +0800</pubDate>
    <dc:creator>neal</dc:creator>
    <guid>https://top.zhongtongzttb.com.cn/?post=60</guid>
</item>
<item>
    <title>Python UI和接口自动化测试指南</title>
    <link>https://top.zhongtongzttb.com.cn/?post=59</link>
    <description><![CDATA[<h3><strong>一、UI自动化测试</strong></h3>
<p>主要用于模拟用户操作（点击、输入、滑动等），验证界面交互功能。</p>
<h4><strong>常用工具</strong></h4>
<ol>
<li><strong>Selenium</strong>（主流Web UI自动化工具）
<ul>
<li>支持多种浏览器（Chrome/Firefox/Edge等）</li>
<li>支持多语言（Python/Java等）</li>
</ul></li>
<li><strong>PyAutoGUI</strong>（跨平台，支持桌面应用和Web）</li>
<li><strong>Appium</strong>（移动端App自动化）</li>
</ol>
<hr />
<h4><strong>Selenium 示例</strong></h4>
<p>python</p>
<p>复制</p>
<pre><code>from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

# 1. 启动浏览器
driver = webdriver.Chrome()  # 需下载对应版本的chromedriver并配置环境变量

# 2. 打开页面
driver.get("https://www.baidu.com")

# 3. 定位元素并操作（显式等待优化稳定性）
search_box = WebDriverWait(driver, 10).until(
    EC.presence_of_element_located((By.ID, "kw"))
)
search_box.send_keys("Python自动化测试")

# 4. 点击搜索按钮
driver.find_element(By.ID, "su").click()

# 5. 验证结果
WebDriverWait(driver, 10).until(
    EC.title_contains("Python自动化测试")
)
assert "Python自动化测试" in driver.title

# 6. 关闭浏览器
driver.quit()</code></pre>
<h4><strong>最佳实践</strong></h4>
<ul>
<li>使用 <code>WebDriverWait</code> 显式等待，避免硬性等待（如 <code>time.sleep</code>）</li>
<li>采用 <strong>Page Object 模式</strong>（PO设计模式）分离页面元素和测试逻辑</li>
<li>结合 <code>pytest</code> 或 <code>unittest</code> 管理测试用例</li>
</ul>
<hr />
<h3><strong>二、接口自动化测试</strong></h3>
<p>验证API的功能、性能及数据正确性。</p>
<h4><strong>常用工具</strong></h4>
<ol>
<li><strong>Requests</strong>（发送HTTP请求）</li>
<li><strong>unittest/pytest</strong>（测试框架）</li>
<li><strong>Pytest + Requests</strong>（主流组合）</li>
<li><strong>FastAPI/Flask Test Client</strong>（测试自身开发的API）</li>
</ol>
<hr />
<h4><strong>接口测试示例（Pytest + Requests）</strong></h4>
<p>python</p>
<p>复制</p>
<pre><code>import requests
import pytest

# 定义测试用例
def test_get_api():
    url = "https://api.example.com/users/1"
    response = requests.get(url)
    assert response.status_code == 200
    assert response.json()["username"] == "test_user"

def test_post_api():
    url = "https://api.example.com/login"
    data = {"username": "admin", "password": "123456"}
    response = requests.post(url, json=data)
    assert response.status_code == 200
    assert "token" in response.json()

# 使用pytest运行测试
# 命令行执行: pytest test_api.py</code></pre>
<h4><strong>增强功能</strong></h4>
<ol>
<li>
<p><strong>参数化测试</strong>（多组输入验证）：<br />
python</p>
<p>复制</p>
<pre><code>@pytest.mark.parametrize("user_id, expected_username", [
   (1, "user1"),
   (2, "user2"),
])
def test_multiple_users(user_id, expected_username):
   response = requests.get(f"https://api.example.com/users/{user_id}")
   assert response.json()["username"] == expected_username</code></pre>
</li>
<li><strong>环境配置分离</strong>（通过配置文件或 <code>.env</code> 管理不同环境URL）</li>
<li><strong>数据清理</strong>（如测试后删除测试数据）</li>
</ol>
<hr />
<h3><strong>三、进阶工具链</strong></h3>
<ol>
<li><strong>测试报告</strong>：
<ul>
<li><strong>Allure Framework</strong>：生成美观的HTML报告</li>
<li><strong>pytest-html</strong>：简单生成测试报告</li>
</ul></li>
<li><strong>持续集成</strong>（CI/CD）：
<ul>
<li>集成到 <strong>Jenkins</strong>、<strong>GitHub Actions</strong> 或 <strong>GitLab CI</strong></li>
</ul></li>
<li><strong>Mock 服务</strong>：
<ul>
<li>使用 <strong>unittest.mock</strong> 或 <strong>pytest-mock</strong> 模拟依赖接口</li>
</ul></li>
</ol>
<hr />
<h3><strong>四、注意事项</strong></h3>
<ol>
<li><strong>UI测试</strong>：
<ul>
<li>元素定位优先使用 <code>ID</code> 或 <code>XPath</code>，避免依赖不稳定的CSS类名</li>
<li>注意动态加载内容的等待策略</li>
</ul></li>
<li><strong>接口测试</strong>：
<ul>
<li>关注状态码、响应时间、数据格式和业务逻辑正确性</li>
<li>对敏感接口添加鉴权（如Token验证）</li>
</ul></li>
</ol>]]></description>
    <pubDate>Mon, 24 Mar 2025 17:06:46 +0800</pubDate>
    <dc:creator>neal</dc:creator>
    <guid>https://top.zhongtongzttb.com.cn/?post=59</guid>
</item>
<item>
    <title>Python自动化测试指南</title>
    <link>https://top.zhongtongzttb.com.cn/?post=58</link>
    <description><![CDATA[<h3><strong>1. 自动化测试类型</strong></h3>
<p>在开始之前，先了解常见的自动化测试类型：</p>
<ul>
<li><strong>单元测试（Unit Testing）</strong>：测试代码的最小单元（如函数、类）。</li>
<li><strong>集成测试（Integration Testing）</strong>：测试多个模块的协作。</li>
<li><strong>端到端测试（E2E Testing）</strong>：模拟用户操作，测试完整流程（如 Web 应用、移动应用）。</li>
<li><strong>API 测试</strong>：验证 API 的请求和响应。</li>
<li><strong>性能测试</strong>：评估系统在高负载下的表现。</li>
</ul>
<hr />
<h3><strong>2. Python 自动化测试常用框架</strong></h3>
<h4><strong>(1) 单元测试框架</strong></h4>
<ul>
<li>
<p><strong>unittest</strong>（Python 内置）</p>
<ul>
<li>基于 JUnit 设计，支持测试用例、测试套件、断言等。</li>
<li>示例：<br />
python</li>
</ul>
<p>复制</p>
<pre><code>import unittest

def add(a, b):
    return a + b

class TestMath(unittest.TestCase):
    def test_add(self):
        self.assertEqual(add(2, 3), 5)

if __name__ == '__main__':
    unittest.main()</code></pre>
</li>
<li>
<p><strong>pytest</strong></p>
<ul>
<li>更简洁灵活，支持参数化测试、插件扩展。</li>
<li>示例：<br />
python</li>
</ul>
<p>复制</p>
<pre><code>def add(a, b):
    return a + b

def test_add():
    assert add(2, 3) == 5</code></pre>
<ul>
<li>运行命令：<code>pytest test_math.py</code></li>
</ul>
</li>
</ul>
<h4><strong>(2) Web 自动化测试</strong></h4>
<ul>
<li>
<p><strong>Selenium</strong></p>
<ul>
<li>用于浏览器自动化，支持 Chrome、Firefox 等。</li>
<li>示例：<br />
python</li>
</ul>
<p>复制</p>
<pre><code>from selenium import webdriver

driver = webdriver.Chrome()
driver.get("https://www.google.com")
search_box = driver.find_element("name", "q")
search_box.send_keys("Python自动化测试")
search_box.submit()
driver.quit()</code></pre>
</li>
<li>
<p><strong>Playwright</strong>（推荐）</p>
<ul>
<li>新一代浏览器自动化工具，支持多浏览器、无头模式、网络拦截等。</li>
<li>示例：<br />
python</li>
</ul>
<p>复制</p>
<pre><code>from playwright.sync_api import sync_playwright

with sync_playwright() as p:
    browser = p.chromium.launch()
    page = browser.new_page()
    page.goto("https://www.google.com")
    page.fill("input[name=q]", "Python自动化测试")
    page.press("input[name=q]", "Enter")
    browser.close()</code></pre>
</li>
</ul>
<h4><strong>(3) API 测试</strong></h4>
<ul>
<li>
<p><strong>requests</strong> + <strong>pytest</strong></p>
<ul>
<li>发送 HTTP 请求并验证响应。</li>
<li>示例：<br />
python</li>
</ul>
<p>复制</p>
<pre><code>import requests

def test_api_status_code():
    response = requests.get("https://api.example.com/users")
    assert response.status_code == 200</code></pre>
</li>
<li>
<p><strong>FastAPI TestClient</strong>（针对 FastAPI 应用）</p>
<ul>
<li>示例：<br />
python</li>
</ul>
<p>复制</p>
<pre><code>from fastapi.testclient import TestClient
from myapp.main import app

client = TestClient(app)

def test_read_item():
    response = client.get("/items/1")
    assert response.status_code == 200</code></pre>
</li>
</ul>
<h4><strong>(4) 移动端测试</strong></h4>
<ul>
<li><strong>Appium</strong>
<ul>
<li>支持 Android 和 iOS 应用的自动化测试。</li>
<li>示例代码类似 Selenium。</li>
</ul></li>
</ul>
<hr />
<h3><strong>3. 测试最佳实践</strong></h3>
<ul>
<li><strong>保持测试独立</strong>：每个测试用例不依赖其他测试结果。</li>
<li><strong>清晰的命名</strong>：测试函数名应描述测试目标（如 <code>test_login_with_invalid_password</code>）。</li>
<li><strong>数据驱动测试</strong>：使用参数化测试（如 <code>@pytest.mark.parametrize</code>）覆盖多组输入。</li>
<li><strong>Mock 外部依赖</strong>：使用 <code>unittest.mock</code> 或 <code>pytest-mock</code> 模拟数据库、API 调用等。</li>
<li><strong>持续集成（CI）</strong>：将测试集成到 CI/CD 流程（如 GitHub Actions、Jenkins）。</li>
</ul>
<hr />
<h3><strong>4. 常用工具和库</strong></h3>
<ul>
<li><strong>覆盖率报告</strong>：使用 <code>coverage</code> 库生成代码覆盖率报告。
<ul>
<li>命令：<code>coverage run -m pytest &amp;&amp; coverage report</code></li>
</ul></li>
<li><strong>测试报告</strong>：使用 <code>pytest-html</code> 生成 HTML 测试报告。
<ul>
<li>命令：<code>pytest --html=report.html</code></li>
</ul></li>
<li><strong>环境管理</strong>：用 <code>virtualenv</code> 或 <code>poetry</code> 隔离项目依赖。</li>
</ul>
<hr />
<h3><strong>5. 示例：完整的 pytest + Selenium 测试</strong></h3>
<p>python</p>
<p>复制</p>
<pre><code># test_web.py
import pytest
from selenium import webdriver

@pytest.fixture(scope="module")
def browser():
    driver = webdriver.Chrome()
    yield driver
    driver.quit()

def test_google_search(browser):
    browser.get("https://www.google.com")
    search_box = browser.find_element("name", "q")
    search_box.send_keys("Python自动化测试")
    search_box.submit()
    assert "Python自动化测试" in browser.title</code></pre>
<p>运行命令：</p>
<p>bash</p>
<p>复制</p>
<pre><code>pytest test_web.py -v</code></pre>
<hr />
<h3><strong>6. 持续集成（CI）示例</strong></h3>
<p>在 GitHub Actions 中配置自动化测试：</p>
<p>yaml</p>
<p>复制</p>
<pre><code># .github/workflows/tests.yml
name: Python Tests

on: [push]

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - name: Set up Python
        uses: actions/setup-python@v2
        with:
          python-version: '3.9'
      - name: Install dependencies
        run: pip install -r requirements.txt
      - name: Run tests
        run: pytest</code></pre>]]></description>
    <pubDate>Mon, 24 Mar 2025 17:05:36 +0800</pubDate>
    <dc:creator>neal</dc:creator>
    <guid>https://top.zhongtongzttb.com.cn/?post=58</guid>
</item>
<item>
    <title>内江旅游景点美食攻略</title>
    <link>https://top.zhongtongzttb.com.cn/?post=57</link>
    <description><![CDATA[<p>内江位于四川盆地东南部，素有“甜城”美誉，因历史上盛产甘蔗、蜜饯而得名。这里历史文化底蕴深厚，自然风光独特，美食丰富，是一处适合休闲游的小众目的地。以下是一份内江旅游攻略，供参考：</p>
<hr />
<h3><strong>一、必游景点推荐</strong></h3>
<ol>
<li><strong>张大千纪念馆</strong>
<ul>
<li>内江是国画大师张大千的故乡，纪念馆展示了他的生平、艺术成就和珍贵作品，是艺术爱好者必打卡之地。</li>
<li><strong>地址</strong>：内江市东兴区东桐路圆顶山。</li>
</ul></li>
<li><strong>隆昌石牌坊群</strong>
<ul>
<li>全国重点文物保护单位，现存明清石牌坊17座，雕刻精美，记录了古代“孝、节、忠、义”的文化故事。</li>
<li><strong>特色</strong>：南关古镇、云峰关牌坊群，适合拍照和感受历史。</li>
<li><strong>地址</strong>：隆昌市金鹅镇。</li>
</ul></li>
<li><strong>圣水寺</strong>
<ul>
<li>川南著名古刹，始建于唐代，寺内有千年古树和灵泉“圣水”，建筑古朴，香火旺盛。</li>
<li><strong>地址</strong>：内江市市中区圣江路。</li>
</ul></li>
<li><strong>古宇湖</strong>
<ul>
<li>国家4A级景区，湖面宽阔，冬季是候鸟栖息地，适合环湖骑行、观鸟或泛舟。</li>
<li><strong>地址</strong>：隆昌市古湖街道。</li>
</ul></li>
<li><strong>资中罗泉古镇</strong>
<ul>
<li>千年盐业古镇，保留明清建筑风格，推荐参观盐神庙、罗泉会议遗址，感受慢生活。</li>
<li><strong>特色美食</strong>：罗泉豆腐宴。</li>
</ul></li>
<li><strong>威远骑龙坳</strong>
<ul>
<li>被称为“川南最美云雾之乡”，雨后清晨常现云海，是摄影爱好者的天堂。</li>
<li><strong>最佳季节</strong>：5-10月雨季。</li>
</ul></li>
</ol>
<hr />
<h3><strong>二、特色美食推荐</strong></h3>
<ol>
<li><strong>内江牛肉面</strong>
<ul>
<li>麻辣鲜香，面条筋道，牛肉软糯，本地人早餐首选。推荐店铺：寡妇面、蔡氏牛肉面。</li>
</ul></li>
<li><strong>油炸粑</strong>
<ul>
<li>糯米包裹绿豆馅油炸而成，外酥里嫩，街头常见小吃。</li>
</ul></li>
<li><strong>王记牛肉干</strong>
<ul>
<li>内江老字号，麻辣、五香口味可选，适合作为伴手礼。</li>
</ul></li>
<li><strong>黄老五花生酥</strong>
<ul>
<li>威远特产，酥脆香甜，非物质文化遗产。</li>
</ul></li>
<li><strong>蜜饯</strong>
<ul>
<li>内江传统甜食，橘饼、冬条、樱桃蜜饯等，甜而不腻。</li>
</ul></li>
</ol>
<hr />
<h3><strong>三、交通指南</strong></h3>
<ul>
<li><strong>外部交通</strong>
<ul>
<li>高铁：成渝高铁经停内江北站，成都/重庆出发约1小时可达。</li>
<li>自驾：成都出发约2小时，重庆约2.5小时。</li>
</ul></li>
<li><strong>市内交通</strong>
<ul>
<li>公交车覆盖主要景点，出租车起步价5元；建议自驾或包车前往周边景点（如隆昌、资中）。</li>
</ul></li>
</ul>
<hr />
<h3><strong>四、住宿推荐</strong></h3>
<ul>
<li><strong>市区</strong>：选择东兴区或市中区，推荐星级酒店如内江万达嘉华酒店，或性价比高的连锁酒店。</li>
<li><strong>隆昌/资中</strong>：若计划深度游，可住当地特色民宿或商务酒店。</li>
</ul>
<hr />
<h3><strong>五、最佳旅游季节</strong></h3>
<ul>
<li><strong>春秋季（3-5月、9-11月）</strong>：气候宜人，适合户外活动。</li>
<li><strong>夏季</strong>：可到古宇湖、骑龙坳避暑，但需注意防晒。</li>
<li><strong>冬季</strong>：古宇湖观鸟，但天气较阴冷。</li>
</ul>
<hr />
<h3><strong>六、行程建议</strong></h3>
<ul>
<li><strong>一日游</strong>：张大千纪念馆 + 圣水寺 + 内江老街（品牛肉面、蜜饯）。</li>
<li><strong>两日游</strong>：
<ul>
<li>Day1：内江市区（张大千纪念馆、圣水寺）→ 隆昌石牌坊群、古宇湖。</li>
<li>Day2：资中罗泉古镇 → 威远骑龙坳（摄影或云雾观赏）。</li>
</ul></li>
</ul>
<hr />
<h3><strong>七、温馨提示</strong></h3>
<ol>
<li>内江景点相对分散，建议提前规划路线，预留充足时间。</li>
<li>尊重当地文化，参观寺庙、牌坊时注意礼仪。</li>
<li>夏季多雨，备好雨具；冬季潮湿，注意保暖。</li>
<li>若时间充裕，可顺路游览周边自贡（恐龙博物馆）、宜宾（蜀南竹海）等地。</li>
</ol>
<p>希望这份攻略能助你玩转内江，感受这座“甜城”的独特魅力！</p>]]></description>
    <pubDate>Fri, 21 Mar 2025 16:35:40 +0800</pubDate>
    <dc:creator>neal</dc:creator>
    <guid>https://top.zhongtongzttb.com.cn/?post=57</guid>
</item>
<item>
    <title>App离线推送解决方案详解</title>
    <link>https://top.zhongtongzttb.com.cn/?post=56</link>
    <description><![CDATA[<h3><strong>1. 操作系统级推送</strong></h3>
<h4><strong>iOS平台</strong></h4>
<ul>
<li><strong>APNs (Apple Push Notification Service)</strong>
<ul>
<li>必须集成，是iOS唯一官方推送通道。</li>
<li>实现步骤：
<ol>
<li>生成APNs证书或密钥（需Apple开发者账号）。</li>
<li>服务端通过APNs API发送推送（支持HTTP/2或基于Token的认证）。</li>
<li>客户端注册设备Token并回传服务器。</li>
</ol></li>
<li>特点：系统级通道，应用关闭时仍可送达，但依赖网络状态。</li>
</ul></li>
</ul>
<h4><strong>Android平台</strong></h4>
<ul>
<li><strong>FCM (Firebase Cloud Messaging)</strong>
<ul>
<li>谷歌官方推送服务，海外Android设备主要依赖此通道。</li>
<li>缺点：国内因网络限制无法稳定使用。</li>
<li>替代方案：需集成国内厂商推送通道。</li>
</ul></li>
</ul>
<hr />
<h3><strong>2. 国内安卓厂商推送通道</strong></h3>
<p>国内主流手机厂商均提供自有推送服务，需逐个集成以提高推送到达率：</p>
<ul>
<li><strong>华为推送（HMS Push）</strong></li>
<li><strong>小米推送（Mi Push）</strong></li>
<li><strong>OPPO推送</strong></li>
<li><strong>vivo推送</strong></li>
<li><strong>荣耀推送</strong></li>
<li><strong>魅族推送</strong></li>
</ul>
<p><strong>实现方式</strong>：</p>
<ul>
<li>为每个厂商单独申请开发者账号，集成对应SDK。</li>
<li>服务端根据设备厂商类型调用不同API发送推送。</li>
<li><strong>优点</strong>：系统级通道，应用进程关闭时仍可唤醒。</li>
<li><strong>缺点</strong>：维护成本高，需适配多套接口。</li>
</ul>
<hr />
<h3><strong>3. 第三方推送平台（推荐）</strong></h3>
<p>为简化多厂商推送适配，可采用第三方推送服务商，例如：</p>
<ul>
<li><strong>个推（Getui）</strong></li>
<li><strong>极光推送（JPush）</strong></li>
<li><strong>友盟推送（UMeng）</strong></li>
<li><strong>腾讯移动推送（TPNS）</strong></li>
<li><strong>阿里云移动推送</strong></li>
</ul>
<p><strong>优势</strong>：</p>
<ul>
<li>统一API：一次集成，自动分发到各厂商通道。</li>
<li>数据统计：支持推送到达率、点击率等分析。</li>
<li>节省成本：避免维护多个厂商后台。</li>
</ul>
<p><strong>实现步骤</strong>：</p>
<ol>
<li>集成第三方SDK到客户端。</li>
<li>服务端调用第三方API发送推送。</li>
<li>SDK自动根据设备厂商选择最优通道。</li>
</ol>
<hr />
<h3><strong>4. 自建长连接推送（可选）</strong></h3>
<p>适用于对实时性要求极高或需完全自主控制的场景：</p>
<ul>
<li><strong>技术方案</strong>：
<ul>
<li>使用协议：MQTT、WebSocket、TCP长连接。</li>
<li>客户端维持与服务器的持久连接，及时接收消息。</li>
</ul></li>
<li><strong>挑战</strong>：
<ul>
<li>电量消耗较高。</li>
<li>安卓系统后台限制（需结合保活策略，但可能影响用户体验）。</li>
<li>高并发下的服务器稳定性。</li>
</ul></li>
</ul>
<hr />
<h3><strong>5. 推送策略优化</strong></h3>
<ul>
<li><strong>用户分群</strong>：根据用户行为、标签发送个性化推送。</li>
<li><strong>定时推送</strong>：选择用户活跃时间段发送。</li>
<li><strong>A/B测试</strong>：对比不同文案的点击率。</li>
<li><strong>沉默用户唤醒</strong>：结合短信、邮件等多渠道触达。</li>
<li><strong>合规性</strong>：遵循《个人信息保护法》，提供用户关闭推送选项。</li>
</ul>
<hr />
<h3><strong>6. 关键注意事项</strong></h3>
<ol>
<li><strong>权限引导</strong>：首次启动时请求通知权限，并提供引导说明。</li>
<li><strong>厂商限制</strong>：
<ul>
<li>部分厂商（如小米、OPPO）要求应用上架商店后才开放推送权限。</li>
<li>厂商通道可能有每日推送限额。</li>
</ul></li>
<li><strong>推送内容规范</strong>：
<ul>
<li>避免敏感词，防止被厂商拦截。</li>
<li>iOS需符合Apple推送内容政策（禁止广告、诱导点击等）。</li>
</ul></li>
<li><strong>数据安全</strong>：
<ul>
<li>用户设备信息加密传输。</li>
<li>避免推送中包含敏感数据。</li>
</ul></li>
</ol>
<hr />
<h3><strong>7. 技术实现流程示例</strong></h3>
<ol>
<li><strong>客户端</strong>：
<ul>
<li>集成第三方SDK（如个推）。</li>
<li>注册设备Token并上传至服务端。</li>
</ul></li>
<li>
<p><strong>服务端</strong>：</p>
<ul>
<li>存储设备Token及关联的用户ID。</li>
<li>
<p>调用第三方API发送推送，示例代码（Python）：<br />
python</p>
<p>复制</p>
<pre><code>import requests

url = "https://restapi.getui.com/v2/{app_id}/push/single"
headers = {
 "Content-Type": "application/json",
 "token": "your_token"
}
data = {
 "audience": {"cid": "client_id"},
 "push_message": {
     "notification": {
         "title": "新消息",
         "body": "您有一条未读通知"
     }
 }
}
response = requests.post(url, json=data, headers=headers)</code></pre>
</li>
</ul>
</li>
<li><strong>运维监控</strong>：
<ul>
<li>监控推送成功率，失败时自动重试。</li>
<li>分析用户关闭推送的原因，优化推送策略。</li>
</ul></li>
</ol>
<hr />
<h3><strong>8. 常见问题排查</strong></h3>
<ul>
<li><strong>推送未到达</strong>：
<ul>
<li>检查设备Token是否失效（如用户重装App或禁用通知）。</li>
<li>厂商通道是否配置正确（如华为推送需配置agconnect-services.json）。</li>
</ul></li>
<li><strong>延迟过高</strong>：
<ul>
<li>切换长连接或优化服务端推送队列。</li>
</ul></li>
<li><strong>合规风险</strong>：
<ul>
<li>确保用户可一键退订，避免频繁打扰。</li>
</ul></li>
</ul>]]></description>
    <pubDate>Fri, 21 Mar 2025 13:58:14 +0800</pubDate>
    <dc:creator>neal</dc:creator>
    <guid>https://top.zhongtongzttb.com.cn/?post=56</guid>
</item>
<item>
    <title>Python爬虫技术与实现方法</title>
    <link>https://top.zhongtongzttb.com.cn/?post=55</link>
    <description><![CDATA[<h3><strong>一、基础爬虫方法</strong></h3>
<h4>1. <strong>Requests + BeautifulSoup</strong></h4>
<ul>
<li><strong>适用场景</strong>：静态网页抓取（无复杂 JavaScript）。</li>
<li>
<p><strong>示例代码</strong>：<br />
python</p>
<pre><code>import requests
from bs4 import BeautifulSoup

url = 'https://example.com'
response = requests.get(url)
if response.status_code == 200:
  soup = BeautifulSoup(response.text, 'html.parser')
  titles = soup.find_all('h1')
  for title in titles:
      print(title.text)</code></pre>
</li>
</ul>
<h4>2. <strong>正则表达式（Regex）</strong></h4>
<ul>
<li>
<p><strong>适用场景</strong>：快速提取特定模式的文本。<br />
python</p>
<pre><code>import re
text = '&lt;h1&gt;Hello World&lt;/h1&gt;'
match = re.search(r'&lt;h1&gt;(.*?)&lt;/h1&gt;', text)
if match:
  print(match.group(1))  # 输出: Hello World</code></pre>
</li>
</ul>
<hr />
<h3><strong>二、动态网页爬取</strong></h3>
<h4>1. <strong>Selenium</strong></h4>
<ul>
<li><strong>适用场景</strong>：需要模拟浏览器操作（如点击、滚动、登录）。</li>
<li>
<p><strong>示例代码</strong>：<br />
python</p>
<pre><code>from selenium import webdriver
from selenium.webdriver.common.by import By

driver = webdriver.Chrome()
driver.get('https://example.com')
element = driver.find_element(By.TAG_NAME, 'h1')
print(element.text)
driver.quit()</code></pre>
</li>
</ul>
<h4>2. <strong>Playwright</strong></h4>
<ul>
<li>
<p><strong>更高效的浏览器自动化工具</strong>：<br />
python</p>
<pre><code>from playwright.sync_api import sync_playwright

with sync_playwright() as p:
  browser = p.chromium.launch()
  page = browser.new_page()
  page.goto('https://example.com')
  print(page.inner_text('h1'))
  browser.close()</code></pre>
</li>
</ul>
<hr />
<h3><strong>三、爬虫框架</strong></h3>
<h4>1. <strong>Scrapy</strong></h4>
<ul>
<li><strong>适用场景</strong>：大型项目，支持异步、中间件、数据管道。</li>
<li>
<p><strong>创建项目</strong>：<br />
bash</p>
<pre><code>scrapy startproject myproject
scrapy genspider example example.com</code></pre>
</li>
<li>
<p><strong>Spider 示例</strong>：<br />
python</p>
<pre><code>import scrapy

class ExampleSpider(scrapy.Spider):
  name = 'example'
  start_urls = ['https://example.com']

  def parse(self, response):
      yield {'title': response.css('h1::text').get()}</code></pre>
</li>
</ul>
<h4>2. <strong>PySpider</strong></h4>
<ul>
<li><strong>可视化分布式爬虫框架</strong>，适合中等规模项目。</li>
</ul>
<hr />
<h3><strong>四、反爬虫策略与应对</strong></h3>
<ol>
<li><strong>常见反爬手段</strong>：
<ul>
<li>User-Agent 检测</li>
<li>IP 封禁</li>
<li>验证码</li>
<li>请求频率限制</li>
</ul></li>
<li>
<p><strong>应对方法</strong>：</p>
<ul>
<li>
<p><strong>设置请求头</strong>：<br />
python</p>
<pre><code>headers = {
 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36'
}
requests.get(url, headers=headers)</code></pre>
</li>
<li>
<p><strong>使用代理 IP</strong>：<br />
python</p>
<pre><code>proxies = {'http': 'http://10.10.1.10:3128'}
requests.get(url, proxies=proxies)</code></pre>
</li>
<li>
<p><strong>降低请求频率</strong>：<br />
python</p>
<pre><code>import time
time.sleep(2)  # 每次请求间隔 2 秒</code></pre>
</li>
<li><strong>处理验证码</strong>：使用 OCR 库（如 Tesseract）或第三方 API。</li>
</ul>
</li>
</ol>
<hr />
<h3><strong>五、数据存储</strong></h3>
<ol>
<li>
<p><strong>保存到文件</strong>：<br />
python</p>
<pre><code>import csv
with open('data.csv', 'w', newline='') as f:
   writer = csv.writer(f)
   writer.writerow(['Title'])
   writer.writerow(['Example Title'])</code></pre>
</li>
<li>
<p><strong>保存到数据库（如 MongoDB）</strong>：<br />
python</p>
<pre><code>from pymongo import MongoClient
client = MongoClient('localhost', 27017)
db = client['mydatabase']
collection = db['mycollection']
collection.insert_one({'title': 'Example'})</code></pre>
</li>
</ol>
<hr />
<h3><strong>六、注意事项</strong></h3>
<ol>
<li><strong>遵守法律法规</strong>：
<ul>
<li>查看目标网站的 <code>robots.txt</code>（如 <code>https://example.com/robots.txt</code>）。</li>
<li>避免侵犯隐私或版权数据。</li>
</ul></li>
<li><strong>道德爬虫</strong>：
<ul>
<li>控制请求频率，避免对服务器造成压力。</li>
<li>标注数据来源。</li>
</ul></li>
</ol>
<hr />
<h3><strong>七、高级技巧</strong></h3>
<ol>
<li>
<p><strong>异步爬虫（aiohttp + asyncio）</strong>：<br />
python</p>
<pre><code>import aiohttp
import asyncio

async def fetch(url):
   async with aiohttp.ClientSession() as session:
       async with session.get(url) as response:
           return await response.text()

urls = ['https://example.com/page1', 'https://example.com/page2']
tasks = [fetch(url) for url in urls]
pages = asyncio.run(asyncio.gather(*tasks))</code></pre>
</li>
<li>
<p><strong>使用 API</strong>：</p>
<ul>
<li>直接调用网站提供的 API 接口（如 <code>https://api.example.com/data</code>）。</li>
</ul>
</li>
</ol>]]></description>
    <pubDate>Fri, 21 Mar 2025 11:54:17 +0800</pubDate>
    <dc:creator>neal</dc:creator>
    <guid>https://top.zhongtongzttb.com.cn/?post=55</guid>
</item>
<item>
    <title>骏河屋API接口申请指南</title>
    <link>https://top.zhongtongzttb.com.cn/?post=54</link>
    <description><![CDATA[<p>关于骏河屋（Suruga-ya）的公开API接口申请，目前骏河屋官方并未明确提供面向公众的开放API服务。以下是相关信息和建议：</p>
<hr />
<h3><strong>1. 官方渠道查询</strong></h3>
<ul>
<li><strong>访问官网</strong>：建议直接访问骏河屋的官方网站（<a href="https://www.suruga-ya.jp/">https://www.suruga-ya.jp</a>），查看是否有“开发者支持”或“API文档”相关页面。通常这类信息会位于网站底部或“企业合作”栏目中。</li>
<li><strong>联系客服</strong>：若官网上无明确说明，可通过邮件或电话联系其客服团队（需使用日语），询问是否有提供API服务的计划或合作方式。</li>
</ul>
<hr />
<h3><strong>2. 可能的替代方案</strong></h3>
<ul>
<li><strong>合作伙伴计划</strong>：部分企业会为合作伙伴或批发客户提供内部API接口。如果你是商家或企业用户，可以尝试通过商业合作的形式申请。</li>
<li><strong>爬虫技术</strong>：如果没有API，部分开发者会通过网页爬虫（Web Scraping）获取数据，但需注意：
<ul>
<li><strong>合法性</strong>：需仔细阅读骏河屋的《利用规约》，确认是否允许自动化访问。</li>
<li><strong>道德风险</strong>：频繁请求可能对服务器造成压力，建议控制频率并遵守 <code>robots.txt</code>规则。</li>
</ul></li>
</ul>
<hr />
<h3><strong>3. 其他资源</strong></h3>
<ul>
<li><strong>第三方平台</strong>：某些日本电商聚合平台（如価格.com、Rakuten等）可能提供商品数据API，可间接获取部分信息。</li>
<li><strong>开发者论坛</strong>：在技术社区（如GitHub、Stack Overflow、日本2ch论坛）搜索是否有非官方API或开源项目分享。</li>
</ul>]]></description>
    <pubDate>Fri, 21 Mar 2025 11:49:34 +0800</pubDate>
    <dc:creator>neal</dc:creator>
    <guid>https://top.zhongtongzttb.com.cn/?post=54</guid>
</item>
<item>
    <title>小程序是否支持打赏功能</title>
    <link>https://top.zhongtongzttb.com.cn/?post=53</link>
    <description><![CDATA[<h3><strong>1. 微信小程序：明确禁止直接打赏功能</strong></h3>
<p>微信官方对小程序中的“打赏”功能有严格限制，主要原因包括：</p>
<ul>
<li><strong>支付场景合规性</strong>：微信要求所有支付行为必须与实际商品或服务交易绑定，而“打赏”属于用户对内容创作者的赠予行为，不符合微信支付的定义。</li>
<li><strong>内容生态管控</strong>：防止通过打赏功能变相支持违规内容（如诱导转发、低俗内容等）。</li>
<li><strong>风险防范</strong>：避免资金流向不透明，防范洗钱等违法行为。</li>
</ul>
<h4><strong>政策依据</strong></h4>
<ul>
<li>微信小程序《运营规范》明确要求：
<ul>
<li><strong>支付需关联真实交易</strong>：所有支付必须对应明确的商品或服务，不得支持无实质内容的“赠予”行为。</li>
<li><strong>禁止虚拟支付</strong>：2020年起，微信进一步收紧了虚拟支付权限，除特定行业（如教育、政务）外，普通小程序无法开通虚拟支付功能。</li>
</ul></li>
</ul>
<h4><strong>替代方案</strong></h4>
<p>若需实现类似打赏的效果，可尝试以下合规方式：</p>
<ol>
<li><strong>内容付费</strong>：将内容包装为知识商品（如文章合集、音频课程），用户通过购买后获取内容。</li>
<li><strong>赞赏码引导</strong>：在小程序内展示微信“赞赏码”，引导用户跳转到微信个人转账页面。</li>
<li><strong>公众号关联</strong>：通过关联公众号，在公众号文章中使用微信原生“喜欢作者”功能（需符合公众号打赏条件）。</li>
</ol>
<hr />
<h3><strong>2. 支付宝小程序：部分场景支持</strong></h3>
<p>支付宝对打赏功能的限制相对宽松，但需符合以下条件：</p>
<ul>
<li><strong>绑定真实服务</strong>：打赏需与具体服务（如咨询、创作内容）关联，不能是纯赠予。</li>
<li><strong>企业资质要求</strong>：需完成企业认证，并开通「当面付」或「电脑网站支付」权限。</li>
<li><strong>报备审核</strong>：需向平台说明打赏的具体用途和场景，通过审核后方可上线。</li>
</ul>
<hr />
<h3><strong>3. 其他平台（字节跳动小程序、百度小程序）</strong></h3>
<ul>
<li><strong>字节跳动（抖音）小程序</strong>：明确禁止无实质交易的支付行为，打赏功能需通过平台“直播打赏”等原生功能实现，不可在小程序内自定义。</li>
<li><strong>百度小程序</strong>：政策类似微信，要求支付必须绑定商品或服务，不支持纯打赏功能。</li>
</ul>
<hr />
<h3><strong>4. 合规建议</strong></h3>
<ul>
<li><strong>避免直接使用“打赏”字样</strong>：可改用“支持作者”“购买内容”等表述，并通过商品交易形式实现。</li>
<li><strong>跳转至其他平台</strong>：引导用户通过外部链接（如H5页面、公众号）完成赠予行为。</li>
<li><strong>关注政策更新</strong>：各平台规则可能调整，需定期查看最新开发者文档。</li>
</ul>
<hr />
<h3><strong>总结</strong></h3>
<ul>
<li><strong>微信小程序</strong>：明确禁止直接打赏，需通过合规的支付场景间接实现。</li>
<li><strong>其他平台</strong>：部分允许但需严格绑定服务，且对企业资质要求较高。</li>
<li><strong>推荐方案</strong>：优先使用平台原生内容变现功能（如微信公众号赞赏、抖音直播打赏），或通过商品化内容满足合规要求。</li>
</ul>]]></description>
    <pubDate>Wed, 19 Mar 2025 17:53:01 +0800</pubDate>
    <dc:creator>neal</dc:creator>
    <guid>https://top.zhongtongzttb.com.cn/?post=53</guid>
</item>
<item>
    <title>极光推送配置好后是否可以直接发起推送消息</title>
    <link>https://top.zhongtongzttb.com.cn/?post=52</link>
    <description><![CDATA[<h3><strong>1. 配置完成后，推送消息的基本流程</strong></h3>
<ul>
<li><strong>服务端推送</strong>：可以通过极光提供的 REST API 或 SDK 直接调用接口发送消息。</li>
<li><strong>控制台推送</strong>：登录极光官网的控制台，手动创建推送任务（适合测试或运营人员）。</li>
<li><strong>客户端测试</strong>：在客户端集成 SDK 后，确保设备已成功注册并获取到有效的 <code>Registration ID</code>。</li>
</ul>
<hr />
<h3><strong>2. 推送前需确认的关键点</strong></h3>
<h4><strong>(1) 客户端配置</strong></h4>
<ul>
<li><strong>SDK 集成</strong>：确保客户端正确集成了极光 SDK（Android/iOS/Web 等），并配置了 <code>AppKey</code>。</li>
<li><strong>权限配置</strong>：
<ul>
<li><strong>Android</strong>：确认 <code>AndroidManifest.xml</code> 中配置了正确的包名、权限、通知渠道等。</li>
<li><strong>iOS</strong>：上传正确的 APNs 证书到极光后台，并确保 Bundle ID 匹配。</li>
</ul></li>
<li><strong>设备注册成功</strong>：检查客户端日志，确认设备已成功注册并获取到 <code>Registration ID</code>（极光后台可查）。</li>
</ul>
<h4><strong>(2) 服务端配置</strong></h4>
<ul>
<li><strong>API 权限</strong>：若通过服务端调用 API，需使用 <code>AppKey</code> 和 <code>Master Secret</code> 生成签名（<a href="https://docs.jiguang.cn/jpush/server/push/rest_api_v3_push/">官方文档</a>）。</li>
<li><strong>推送目标设置</strong>：指定推送的受众（如所有用户、特定标签、别名或 Registration ID）。</li>
</ul>
<h4><strong>(3) 网络和证书</strong></h4>
<ul>
<li><strong>APNs 证书</strong>：iOS 推送需确保极光后台的 APNs 证书有效且未过期。</li>
<li><strong>防火墙</strong>：服务端调用极光 API 时，确保网络未拦截 <code>https://api.jpush.cn</code> 的请求。</li>
</ul>
<hr />
<h3><strong>3. 快速测试推送的方法</strong></h3>
<h4><strong>(1) 通过控制台手动推送</strong></h4>
<ol>
<li>登录极光控制台 → 选择应用 → 创建推送。</li>
<li>填写推送内容，选择“全量推送”或指定设备。</li>
<li>发送后，在客户端查看通知栏是否收到消息。</li>
</ol>
<h4><strong>(2) 通过 API 调用（示例）</strong></h4>
<p>使用 <code>curl</code> 测试推送：</p>
<p>bash</p>
<p>复制</p>
<pre><code>curl --location --request POST 'https://api.jpush.cn/v3/push' \
--header 'Authorization: Basic YOUR_BASE64_ENCODED_AUTH_STRING' \  # 格式为 Base64(AppKey:MasterSecret)
--header 'Content-Type: application/json' \
--data-raw '{
    "platform": "all",
    "audience": "all",
    "notification": {
        "alert": "Hello, JPush!"
    }
}'</code></pre>
<h4><strong>(3) 客户端日志检查</strong></h4>
<ul>
<li>查看客户端日志，确认收到推送回调（如 <code>onReceive</code> 事件）。</li>
<li>极光控制台的“推送记录”中可查看推送状态和送达率。</li>
</ul>
<hr />
<h3><strong>4. 常见问题排查</strong></h3>
<ul>
<li><strong>收不到推送</strong>：
<ol>
<li>检查客户端是否成功注册（查看 <code>Registration ID</code> 是否存在）。</li>
<li>检查 APNs 证书是否配置正确（iOS）。</li>
<li>确认推送目标（Audience）是否匹配设备标签/别名。</li>
<li>检查网络是否允许极光域名（如企业内网限制）。</li>
</ol></li>
<li><strong>服务端返回错误</strong>：
<ul>
<li>401 错误：<code>AppKey</code> 或 <code>Master Secret</code> 错误。</li>
<li>403 错误：推送权限未开通或配额不足。</li>
</ul></li>
</ul>
<hr />
<h3><strong>5. 总结</strong></h3>
<p>只要客户端 SDK 集成正确、服务端 API 参数无误，且设备已注册成功，极光推送配置完成后可以直接发起推送。建议首次使用时通过控制台手动推送测试，再逐步接入服务端自动化流程。若遇到问题，可结合极光控制台的“推送记录”和客户端日志定位原因。</p>]]></description>
    <pubDate>Wed, 19 Mar 2025 17:48:24 +0800</pubDate>
    <dc:creator>neal</dc:creator>
    <guid>https://top.zhongtongzttb.com.cn/?post=52</guid>
</item>
<item>
    <title>Python接口自动化测试</title>
    <link>https://top.zhongtongzttb.com.cn/?post=51</link>
    <description><![CDATA[<p>Python 接口自动化测试常用工具<br />
（一）Requests 库<br />
在 Python 接口自动化测试中，Requests 库是一个非常实用的第三方库。它的优势显著，主要体现在以下几个方面：</p>
<p>简单易用：其语法简洁直观，即便是刚接触的新手也能快速上手，轻松地实现各种功能，例如只需要简单几行代码就能完成一个 HTTP 请求的发送与响应获取操作。<br />
功能全面：全面支持如 GET、POST、PUT、DELETE 等多种常见的 HTTP 请求方法，无论是获取资源信息的 GET 请求，还是会修改服务器资源的 POST 请求等，都可以方便地通过它来进行操作。<br />
灵活强大：能够方便地添加请求头、表单数据、JSON 数据等各类请求相关信息，以此来满足不同场景下接口测试的多样化需求。<br />
安装 Requests 库十分便捷，常用的方式是通过 pip 进行安装，只需在命令行中输入 “pip install requests” 即可。若担心下载速度过慢，还可以配置国内镜像源，比如使用国内的一些知名镜像站点，来加快安装的速度。</p>
<pre><code>    使用 Requests 库发送常见的 HTTP 请求也较为简单，下面以 GET 和 POST 请求为例进行介绍：</code></pre>
<p>GET 请求：可以使用requests.get()方法来发送 GET 请求，它有一个必传的参数url，用于指定请求的地址，像访问一个网页获取数据时就可以这样操作。例如想要获取某个网页的内容，代码可能类似如下形式：<br />
import requests<br />
response = requests.get('<a href="https://www.example.com">https://www.example.com</a>')<br />
print(response.text)<br />
上述代码中，通过requests.get()向指定的Example Domain这个 URL 发送 GET 请求，然后使用response.text获取返回的文本内容（也就是网页的 HTML 源码等信息）。而且如果有请求参数需要传递，还可以通过params参数以字典等形式来传入，参数会自动按照规则拼接在 URL 后面。</p>
<p>POST 请求：当需要向服务器提交数据，比如用户注册、登录等场景涉及修改服务器数据时，常使用 POST 请求，通过requests.post()方法来实现。例如模拟用户登录的 POST 请求示例如下：<br />
import requests<br />
login_url = '<a href="https://www.example.com/login">https://www.example.com/login</a>'<br />
login_data = {'username': 'testuser', 'password': '123456'}<br />
response = requests.post(login_url, data=login_data)<br />
print(response.text)<br />
这里指定了登录的 URL 以及以字典形式提供的用户名和密码等登录数据，使用requests.post()将数据发送给服务器，进而可以根据返回的响应内容判断登录是否成功等情况。</p>
<pre><code>    总之，Requests 库在 Python 接口自动化测试中扮演着十分重要的基础角色，为后续的测试工作提供了有力的支持。</code></pre>
<p>（二）PyTest 框架<br />
PyTest 框架是 Python 接口自动化测试中备受青睐的一个工具，具备诸多实用的功能特点。</p>
<pre><code>    首先，它在编写和运行测试用例方面表现出色。编写测试用例时，规则较为简单灵活，测试文件通常以test_开头（以_test结尾也可以），测试类以Test开头且不能带__init__方法，测试函数以test_开头，断言使用基本的assert即可，这种简洁的规范使得测试用例的编写清晰易懂，容易上手。

    在运行测试用例上，方式也多种多样。可以通过命令行运行，比如指定执行的测试文件（常用 “pytest 路径 /py 文件名” 这种形式，默认搜索的是test开头的文件，Test开头的类，小写的test开头的方法），还可以带其他参数运行，像 “pytest 路径 /py 文件名 -v” 可以显示测试的详细参数信息，“pytest 路径 /py 文件名 -s” 能显示测试执行的输出信息等；也可以在脚本里通过pytest.main()来执行测试用例。

    其次，PyTest 框架在生成测试报告方面功能强大，支持生成多种形式的测试报告，并且有许多第三方插件与之配合来扩展其功能，例如pytest-html插件可以完美生成 html 测试报告，方便查看测试结果的详细情况；pytest-rerunfailures插件能实现失败 case 的重试功能，有助于更全面地排查问题；还有pytest-xdist插件可进行多 CPU 分发，提升测试执行的效率等。

    另外，PyTest 框架具备自动发现测试的能力，只要遵循其用例编写规范，它就能自动找到并执行相关的测试用例，无需复杂的配置过程。同时，其丰富的断言机制让测试人员可以方便地对接口返回结果等进行验证，判断是否符合预期。而且插件机制十分灵活，除了上述提到的一些常用插件外，还可以根据具体项目需求自定义扩展插件，使其能够更好地适配不同的测试场景。

    总的来说，PyTest 框架以其简单灵活、功能丰富等优势，在 Python 接口自动化测试中发挥着重要的作用，大大提高了测试工作的效率和质量。</code></pre>
<p>（三）Unittest 框架<br />
Python 内置的 Unittest 框架为接口自动化测试提供了有力的支持，有着自己独特的功能和应用场景。</p>
<pre><code>    它提供了编写测试用例的类和方法，测试用例需要定义在继承自unittest.TestCase的类中，在这个类里，可以定义一些特殊的方法来进行用例执行前的初始化操作以及用例执行后的清理操作。比如setUp()方法会在每个测试用例执行前运行，可以在这里进行如实例化相关类、初始化一些数据等操作；tearDown()方法则在每个测试用例执行后运行，用于清理资源、还原环境等。如果希望这些初始化和清理操作只在整个测试类开始和结束时执行一次，还可以使用类方法setUpClass()和tearDownClass()来替代。

    Unittest 框架支持测试套件（TestSuite）的功能，通过TestSuite可以灵活地组织和选择要执行的测试用例，例如可以将相关的一组测试用例添加到TestSuite中，然后统一执行，方便对不同功能模块的接口测试进行分类管理和执行控制。

    在生成测试报告方面，虽然本身内置的报告形式相对基础，但可以结合一些第三方库（如HTMLTestRunner等）来生成更加美观、详细的 HTML 格式等的测试报告，便于直观地查看测试结果以及分析测试情况。

    在接口自动化测试的实际应用场景中，Unittest 框架常用于对接口的功能性、稳定性等方面进行测试。例如对于一个具有多个接口的项目，可以针对每个接口编写对应的测试用例类，利用setUp()等方法准备好接口请求的相关前置条件（如设置请求的 URL、请求参数等），在测试用例方法中发送接口请求并通过断言来验证接口返回的数据是否符合预期，最后通过测试套件来组织这些用例按照需求进行执行，进而生成测试报告来总结整个测试过程中发现的问题以及接口的质量情况等。

    总之，Unittest 框架凭借其内置的功能特性以及与其他库结合的扩展性，在 Python 接口自动化测试领域有着广泛的应用和重要的地位。</code></pre>
<p>（四）其他常用工具<br />
除了上述的几个主要工具外，在 Python 接口自动化测试中还有一些其他常用的工具也发挥着不可忽视的作用。</p>
<pre><code>    Beautiful Soup 是一个用于解析 HTML 和 XML 文档的 Python 库，在自动化测试中，尤其是涉及到对网页内容进行解析验证的场景时非常有用。例如在测试一个接口返回的 HTML 页面数据是否正确时，通过 Beautiful Soup 可以方便地提取页面中的文本、链接、图片、表格等各种元素，然后与预期的结果进行对比。它提供了简单而直观的 API，支持多种解析器（如 Python 标准库的解析器、lxml、html5lib 等），可以根据具体的需求和性能要求来选择合适的解析器进行文档解析，进而实现对网页内容的高效遍历、搜索和数据提取操作。

    PyCurl 是一个功能强大的库，主要用于处理 HTTP 请求，它底层基于 libcurl 库，能够实现很多复杂的 HTTP 相关操作，像支持多种协议、可以进行文件上传下载、设置复杂的请求头和代理等功能，在需要对接口进行一些高级的、定制化的 HTTP 请求操作时，PyCurl 可以提供很好的支持。

    JSONPath 则是专门用于解析 JSON 数据的工具，在接口自动化测试中，由于很多接口返回的数据格式都是 JSON，使用 JSONPath 可以方便快捷地从复杂的 JSON 数据结构中提取出想要验证的具体数据节点，比如提取某个特定字段的值来判断接口返回的业务数据是否准确，或者验证某个数组中的元素是否符合预期等，极大地提高了对 JSON 格式接口数据的处理和验证效率。

    这些工具在不同的测试场景下，从不同的角度帮助测试人员更好地开展 Python 接口自动化测试工作，拓宽了测试的手段和覆盖范围，提升了整体的测试效果和质量。</code></pre>]]></description>
    <pubDate>Fri, 14 Mar 2025 10:30:16 +0800</pubDate>
    <dc:creator>neal</dc:creator>
    <guid>https://top.zhongtongzttb.com.cn/?post=51</guid>
</item>
<item>
    <title>deepseek常用功能</title>
    <link>https://top.zhongtongzttb.com.cn/?post=50</link>
    <description><![CDATA[<h1>deepseek常用功能</h1>
<ol>
<li><strong>核心功能模块</strong></li>
</ol>
<ul>
<li><strong>文本分类与情感分析</strong><br />
DeepSeek 通过动态稀疏注意力机制处理长文本数据，支持预训练模型微调，可快速实现高性能的文本分类（如新闻分类、情感分析）<em>4</em>。</li>
<li><strong>数据预处理与模型训练</strong><br />
提供完整的数据清洗、特征提取工具，支持端到端的模型训练流程，并内置自动化评估指标（如准确率、F1值）<em>4</em>。</li>
</ul>
<h4>2. <strong>实用操作技巧</strong></h4>
<ul>
<li><strong>高效指令应用</strong><br />
用户可通过25个高效指令快速完成代码生成、数据分析等任务，例如使用 <code>“生成Python递归函数示例”</code>直接获取代码片段<em>2</em>。</li>
<li><strong>角色设定模式</strong><br />
通过指令让DeepSeek扮演特定角色（如资深程序员、学术导师），获得更专业的回答，例如输入 <code>“你是一位数据分析师，请解释线性回归原理”</code><em>3</em>。</li>
</ul>
<h4>3. <strong>扩展与优化</strong></h4>
<ul>
<li><strong>模型轻量化部署</strong><br />
未来计划通过剪枝、量化技术压缩模型，适配边缘设备，降低计算资源需求。</li>
<li><strong>多语言与领域适配</strong><br />
正在扩展多语言支持，并针对医疗、法律等领域优化模型，提升垂直场景的准确性</li>
</ul>]]></description>
    <pubDate>Sat, 08 Mar 2025 20:44:41 +0800</pubDate>
    <dc:creator>neal</dc:creator>
    <guid>https://top.zhongtongzttb.com.cn/?post=50</guid>
</item>
<item>
    <title>deepseek基本教程</title>
    <link>https://top.zhongtongzttb.com.cn/?post=49</link>
    <description><![CDATA[<p>关于DeepSeek使用教程，根据提供的参考资料整理如下分步指引：</p>
<h3>一、快速入门（5分钟掌握基础）</h3>
<ol>
<li>通过引用[1]可知，DeepSeek提供极速入门指南，帮助用户快速完成基础配置。建议首先完成账号注册并体验核心交互功能</li>
<li>初始使用建议关注：
<ul>
<li>基础指令格式识别</li>
<li>数学表达式书写规范（如E=mc2<strong>E</strong>=<strong>m</strong>c<strong>2</strong>）</li>
<li>代码块交互功能<em>1</em></li>
</ul></li>
</ol>
<h3>二、系统学习教程（蓝皮书指南）</h3>
<p>引用[2]详细说明了DAC出品的《DeepSeek使用教程蓝皮书》，该教程包含：</p>
<pre><code>1. 核心功能模块解析
2. 交互式学习方法
3. 本地/云端部署指南
4. 典型应用场景演示（含代码示例）</code></pre>
<p>建议按章节顺序学习，重点掌握API调用规范和错误处理机制<em>2</em></p>
<h3>三、API开发实践</h3>
<p>引用[3]提供API使用专项指南：</p>
<pre><code># API调用示例
import deepseek
api = deepseek.connect(api_key="your_key")
response = api.generate("解释量子计算原理")</code></pre>
<p>需特别注意认证机制和请求频率限制<em>3</em></p>
<h3>四、高级功能拓展</h3>
<p>引用[4]指导用户构建知识库：</p>
<ol>
<li>数据准备规范：建议采用TF−IDF<strong>TF</strong>−<strong>I</strong>D<strong>F</strong>算法预处理文本</li>
<li>
<p>自定义指令训练：通过y=σ(Wx+b)<strong>y</strong>=<strong>σ</strong>(<strong>W</strong>x<strong>+</strong>b<strong>)</strong></p>
<p>等机器学习模型优化响应</p>
</li>
<li>专业场景适配：结合∇⋅E=ρϵ0<strong>∇</strong>⋅<strong>E</strong>=<strong>ϵ</strong>0<strong><strong>ρ</strong></strong>等专业公式增强STEM领域应答</li>
</ol>]]></description>
    <pubDate>Sat, 08 Mar 2025 20:43:53 +0800</pubDate>
    <dc:creator>neal</dc:creator>
    <guid>https://top.zhongtongzttb.com.cn/?post=49</guid>
</item>
<item>
    <title>DeepSeek的使用心法</title>
    <link>https://top.zhongtongzttb.com.cn/?post=48</link>
    <description><![CDATA[<ol>
<li>把问题当快递包裹——写清楚“收件信息”<br />
❌ 错误示范：<br />
“我想减肥，怎么办？”（AI只会给你百科全书式的回答）</li>
</ol>
<p>✅正确操作：<br />
① 加身份标签：<br />
“我是个每天坐办公室的会计，腰椎不好不能剧烈运动，怎么安排减脂饮食？”</p>
<p>② 加具体阻碍：<br />
“孩子总挑食不吃蔬菜，有没有5分钟能搞定的隐藏蔬菜食谱？”</p>
<p>原理：就像你去医院不会只说“我不舒服”，AI也需要知道你的“症状细节”。</p>
<p>你需要把你的需求说清楚，如果你给 AI 是一个模棱两可的问题，那么 AI 也会给你一个大而全的答案！</p>
<ol start="2">
<li>复杂问题玩“分解游戏”<br />
不要一次性问：<br />
“我要开奶茶店，告诉我所有注意事项”</li>
</ol>
<p>试着拆解：</p>
<p>第一阶段：<br />
“在三四线城市小学附近开奶茶店，主打10元以下价位，需要优先考虑哪3个成本项？”</p>
<p>第二阶段：<br />
“针对小学生群体，除了珍珠奶茶，还有哪些健康替代配料方案？”</p>
<p>实测效果：分步提问获得的建议，比一次性的大段回答实用2倍以上。</p>
<ol start="3">
<li>学会给AI“打补丁”<br />
当AI第一次没答到点上，别放弃！用这三句话挽救：</li>
</ol>
<p>“刚才的方案里，‘找供应商’这步能不能展开说？”<br />
“如果预算只有500元，第三点提到的设备能换成更便宜的吗？”<br />
“我是烘焙小白，请用‘完全不会揉面’都能听懂的方式解释第二步”<br />
类比场景：就像网购时和客服沟通，补充信息越多，解决方案越精准。</p>
<ol start="4">
<li>警惕“正确的废话”</li>
</ol>
<p>如果得到这种回答：<br />
“要保持良好作息，注意饮食均衡，适当运动…”</p>
<p>立即追加：<br />
“请直接给我一个可执行的方案，比如：<br />
周一早餐：xx+xx（具体到克数）<br />
周三运动：xx动作（附跟练视频链接）”</p>
<p>核心逻辑： AI默认会给出安全但宽泛的回答，需要你用具体需求“激活”它的深度能力。</p>
<ol start="5">
<li>重要事项加“双重确认”<br />
涉及医疗、法律等专业领域时，务必追加：<br />
“请确认这个建议是否符合2024年最新《xx条例》规定？”<br />
“以上药物配伍是否存在禁忌？请分点列出风险项”</li>
</ol>
<p>保护机制： AI可能遗漏时效性信息，这点和人类专家沟通同理。</p>
<ol start="6">
<li>用“土味例子”理解专业概念<br />
想弄明白区块链？别直接问定义，试试：<br />
“用菜市场王阿姨记账本的故事，解释区块链怎么防止作假”</li>
</ol>
<p>需要理解财报术语？可以问：<br />
“把毛利率、净利率的区别，用烧烤摊进货卖串的利润来比喻”</p>
<p>效果验证： 用生活场景提问，理解效率提升60%以上。</p>
<ol start="7">
<li>给AI“穿职业装”<br />
在问题前加角色设定，回答会瞬间专业：<br />
普通提问：<br />
“帮我写个工作周报”</li>
</ol>
<p>升级版：<br />
“假设你是外企市场总监，用数据驱动型思维帮我润色这份周报，重点突出用户增长策略的迭代效果”</p>
<p>角色库推荐： 心理咨询师、资深HR、小说编辑、营养师等垂直领域专家。</p>
<ol start="8">
<li>把AI当“杠精朋友”<br />
重要决策前，试试这样提问：<br />
“如果我要在老家县城开火锅店，请分别列出：</li>
</ol>
<p>最可能成功的3个理由<br />
最容易失败的3个隐患<br />
用SWOT分析框架对比”<br />
进阶用法：在每轮对话后追问“还有其他可能性吗？”，能挖掘更多隐藏角度。</p>
<ol start="9">
<li>家庭场景的妙用<br />
① 调解矛盾：<br />
“孩子沉迷手机，用非暴力沟通话术设计一段睡前对话”</li>
</ol>
<p>② 生活妙招：<br />
“家里木地板被泡水翘边，在不请工人的情况下，列出分步骤应急处理方案”</p>
<p>③ 亲情维系：<br />
“帮我将这段文字改写成给父母的手写信格式，语气要亲切自然，避免网络用语”</p>
<ol start="10">
<li>终极心法：把它当“实习生”<br />
记住这个关系公式：</li>
</ol>
<p>模糊指令=低质量反馈<br />
具体需求+场景细节=超预期产出<br />
就像你不会对新来的实习生说：“做个好看的PPT”，而会说：“这是市场部的季度数据，用蓝色系商务风格，重点标出环比增长超过15%的部分”。</p>
<p>划重点<br />
遇到AI反复答非所问时：</p>
<p>检查是否用了太多专业术语<br />
把长段落改成1-2行的短需求<br />
加入“不要理论，只要操作步骤”等明确限制<br />
刚开始需要刻意练习，但大约对话20次后，你会形成自己的“提问肌肉记忆”。</p>
<p>现在就从最简单的需求开始试一句：“教我用XXX，我的顾虑是 XXX，请使用大白话表达”——你会发现，用好AI的关键，在于像对待人一样对待它。</p>]]></description>
    <pubDate>Fri, 07 Mar 2025 01:13:48 +0800</pubDate>
    <dc:creator>neal</dc:creator>
    <guid>https://top.zhongtongzttb.com.cn/?post=48</guid>
</item>
<item>
    <title>DeepSeek实用技巧</title>
    <link>https://top.zhongtongzttb.com.cn/?post=47</link>
    <description><![CDATA[<p>一、明确提问方式<br />
避免复杂提示词：DeepSeek是一个推理模型，使用结构化的提示词反而会限制其推理能力，因此建议直接提出问题，让模型自行推理。</p>
<p>清晰表达需求：提问时要明确具体的目标、背景和要求，避免模糊和笼统的表述。例如，不要说“帮我写个方案”，而要说“作为跨境电商创业者，我需要制定亚马逊新品推广方案，请按以下框架展开……”。</p>
<p>二、提问技巧<br />
场景化模板：明确目标、对象、效果和问题。例如，“我要设计一个PPT框架，要给一批50岁左右的制造业老板分享，主题是传统工厂出海战略布局……”。</p>
<p>术语破解模板：用简单的语言解释专业术语，例如“用小学生能听懂的话解释RLHF”。</p>
<p>风格迁移模板：模仿特定作家或文体进行创作，例如“用金庸的武侠小说风格，描写一段程序员使用DeepSeek-R1高效编程的场景”。</p>
<p>三、优化提问结构<br />
4步提问法：明确身份、具体任务、细节约束和输出格式。例如，“作为市场专员，请对比2024年Q4比亚迪与特斯拉的社交媒体声量，分析用户对‘降价策略’的情绪倾向，用表格呈现”。</p>
<p>分步骤提问：对于复杂问题，将其拆分为多个简单步骤，逐步提问。例如，“第一步：总结社交媒体营销的五大趋势；第二步：针对我们的产品，挑选三个最适合的趋势；第三步：设计一套实施计划……”。</p>
<p>四、提供背景信息<br />
背景信息的重要性：提供背景信息可以帮助DeepSeek更好地理解问题的上下文，从而给出更精准的回答。例如，“我正在准备英语四级考试，请用简单词汇解释这篇科技文章的重点”。<br />
五、追问和反馈<br />
追问技巧：通过追问可以进一步挖掘问题的细节和深度。例如，“基于这个方案，可能遇到哪些实施风险？给出应对策略”。</p>
<p>反馈修正：如果回答不符合预期，可以通过补充信息或调整问题来修正回答。例如，“刚才的回答太专业了，请用买菜阿姨能懂的话再说一遍”。</p>
<p>六、指定输出格式<br />
明确输出要求：告诉DeepSeek你希望得到的回答形式，例如列表、表格、分点说明等。例如，“请用对比表格形式展示微波炉vs空气炸锅的加热原理、适用场景和能耗区别”。<br />
七、避免常见错误<br />
避免模糊提问：避免使用过于模糊或笼统的提问方式，例如“这个怎么做？”或“那个东西怎么样？”。</p>
<p>避免多问题同时问：尽量一次只问一个问题，避免同时提出多个问题，以免让回答变得混乱。</p>
<p>避免缺乏关键信息：在提问时提供足够的关键信息，例如在询问代码问题时附上代码和错误信息。</p>
<p>八、高级玩法<br />
角色代入法：让DeepSeek扮演特定角色来回答问题，例如“你是一位资深程序员，请帮我解释一下Python中的递归函数”。</p>
<p>跨模态融合：结合图片、文字、数据等多种模态进行提问，例如“解读这张用户行为热图，点出三个用户流失的关键点，并用箭头标出改进方向”。</p>
<p>逆向提问技巧：当不确定具体需求时，让DeepSeek帮助你列出关键问题，例如“我现在打算开展某个项目，但不太确定具体需求应该怎么描述，请你帮我列出5个关键问题，协助我理清思路”。</p>
<p>九、隐藏功能<br />
直接处理数据：将CSV数据直接粘贴到DeepSeek中，让其进行分析或生成图表代码。</p>
<p>翻译对比：同时要求DeepSeek以不同风格翻译同一句话，例如“把这句话用GPT风格和DeepSeek风格分别翻译成英文”。</p>
<p>当搜索引擎用：通过添加特定关键词（如site:知乎或site:``arxiv.org）让DeepSeek搜索特定网站的信息。</p>
<p>十、避坑指南<br />
简化回答：如果回答过于复杂或专业，可以要求DeepSeek用更简单的方式解释，例如“用小学生能听懂的话解释”。</p>
<p>代码报错：遇到代码问题时，直接粘贴错误信息和代码，让DeepSeek帮助调试。</p>
<p>避免冗长回答：如果不需要详细回答，可以要求DeepSeek只输出核心步骤或关键结论。</p>
<p>十一、总结<br />
把DeepSeek当作一个聪明但没常识的新同事：在提问时要明确具体的目标、背景和要求，避免让其猜测，同时提供足够的信息以帮助其更好地理解问题。</p>
<p>高效提问公式：“身份+任务+要求+例子”，例如“作为健身教练（身份），帮我制定减肥食谱（任务），要一周不重样（要求），像这样（例子）……”。</p>
<p>核心理念：明确告诉DeepSeek你想要什么、参考什么资料、做成什么样子以及避开哪些雷区，这样可以大大提高其回答的准确性和实用性。</p>]]></description>
    <pubDate>Fri, 07 Mar 2025 01:08:58 +0800</pubDate>
    <dc:creator>neal</dc:creator>
    <guid>https://top.zhongtongzttb.com.cn/?post=47</guid>
</item>
<item>
    <title>DeepSeek全场景使用指南：从避坑到高阶玩法</title>
    <link>https://top.zhongtongzttb.com.cn/?post=46</link>
    <description><![CDATA[<p>一、为什么选择DeepSeek？四大核心优势</p>
<ol>
<li>技术性价比革命<br />
✅ 混合专家架构（MoE）：仅激活370亿参数即可实现GPT-4级别性能，推理成本降低80%</li>
</ol>
<p>✅ 中文优化：文言文翻译准确率92.3%，远超国际开源模型<br />
✅ 多模态支持：支持PDF/Word/图片解析，一键生成数据可视化图表</p>
<ol start="2">
<li>全场景覆盖能力<br />
领域   典型应用    效果示例<br />
教育   教案生成/作业批改   5分钟产出《牛顿定律》三维教学目标框架<br />
开发   代码补全/调试 自动修复Python的SettingWithCopyWarning并提供3种优化方案<br />
创作   新媒体文案/视频脚本  生成50条小红书爆款标题，阅读量提升300%</li>
<li>部署零门槛<br />
✅ 网页端免安装：<a href="https://chat.deepseek.com">https://chat.deepseek.com</a></li>
</ol>
<p>✅ 移动端轻量化：微信小程序/APP双端同步，8G内存流畅运行</p>
<p>二、功能速览：三大核心模块<br />
模块  功能亮点    错误示范    正确操作<br />
智能问答    多轮对话溯源验证    &quot;怎么写论文？&quot; → 空泛建议 &quot;生成Transformer架构创新点对比表，附LaTeX公式&quot;<br />
代码助手    全栈开发支持  &quot;写个排序算法&quot; → 生成Python2过时代码    &quot;用Python3.10实现快速排序，添加类型注解与doctest用例&quot;<br />
数据分析    可视化报告生成 &quot;分析销售数据&quot; → 仅文字结论    上传CSV自动生成带热力地<br />
三、正确vs错误示范对照表<br />
场景1：论文写作<br />
❌ 错误提问：</p>
<p>&quot;帮我改论文&quot;<br />
→ 回复：&quot;建议多查文献&quot;（无效指导）</p>
<p>✅ 正确公式：</p>
<p>&quot;我是机械专业本科生，需优化文献综述部分：</p>
<ol>
<li>突出近3年柔性机器人传感器突破</li>
<li>用学术语言重写并标注参考文献DOI</li>
<li>按《计算机学报》格式排版&quot;<br />
→ 生成带权威引用的段落，查重率直降15%</li>
</ol>
<p>场景2：职场周报<br />
❌ 错误提问：</p>
<p>&quot;写份工作总结&quot;<br />
→ 生成&quot;加强学习&quot;等套路内容</p>
<p>✅ 正确操作：</p>
<p>&quot;作为审计顾问，用STAR法则整理年度工作：</p>
<ol>
<li>突出3个IPO项目风险控制贡献</li>
<li>量化节省客户时间成本（精确到小时）</li>
<li>提出2025年CPA学习计划&quot;<br />
→ 输出可直接提交的总结，获合伙人好评</li>
</ol>
<p>四、DeepSeek+跨场景解决方案</p>
<ol>
<li>DeepSeek+教学<br />
[指令模板]<br />
&quot;设计《散步》课文3分钟导入环节：</li>
</ol>
<ul>
<li>结合学生家庭生活案例</li>
<li>包含小组讨论+情景模拟</li>
<li>输出带时间轴的互动流程表&quot;<br />
→ 生成可直接打印的教案框架</li>
</ul>
<ol start="2">
<li>DeepSeek+开发</li>
</ol>
<h1>复杂问题分步求解</h1>
<p>第一轮：&quot;Pandas出现SettingWithCopyWarning怎么办？&quot;第二轮：&quot;请修改以下代码并提供3种预防方案：[粘贴代码]&quot;第三轮：&quot;生成该问题的技术文档模板&quot;3. DeepSeek+自媒体<br />
&quot;生成智能手表营销视频脚本：</p>
<ol>
<li>分'通勤/运动/睡眠'三大场景</li>
<li>每场景包含产品特写镜头描述</li>
<li>结尾设计'抽奖+晒单'双重转化&quot;<br />
→ 自动输出MidJourney提示词+剪映剪辑建议</li>
</ol>
<p>五、避坑指南（血泪经验！）<br />
隐私防护：避免输入身份证/银行卡信息，改用&quot;假设45岁男性患者...&quot;等虚拟案例</p>
<p>信息验证：对学术结论使用&quot;请提供DOI编号&quot;二次验证</p>
<p>格式规范：添加&quot;用Markdown表格/代码块/标题分级&quot;等约束条件</p>]]></description>
    <pubDate>Wed, 05 Mar 2025 21:43:46 +0800</pubDate>
    <dc:creator>neal</dc:creator>
    <guid>https://top.zhongtongzttb.com.cn/?post=46</guid>
</item>
<item>
    <title>DeepSeek使用教程，9个技巧让AI助手变身超级英雄</title>
    <link>https://top.zhongtongzttb.com.cn/?post=45</link>
    <description><![CDATA[<p>深度揭秘DeepSeek：9个技巧让AI助手变身超级英雄<br />
大家好，我是徐师兄~ 最近，DeepSeek这款AI工具如同一颗闪亮的新星，在国内外都掀起了一阵波澜。许多人都在尝试，但也有部分人表示：它似乎并没有想象中的那么强大。</p>
<p>其实，这并不是DeepSeek本身的问题，而是很多人在使用它时，方法不对，导致“宝刀未老，误用其锋”。这就像是拿着超强的武器，却没有找到合适的战斗方式，白白浪费了它的潜力。</p>
<p>今天，我就给大家带来9个超级实用的DeepSeek使用技巧。通过这些技巧，你会发现，DeepSeek比你想象的要强大得多！</p>
<p>DeepSeek学习交流区，长期更新</p>
<p>一、DeepSeek三大模式解析：选择适合的武器，才能事半功倍<br />
DeepSeek有三个核心模式，分别是：基础模型（V3）、深度思考（R1）、联网搜索。这三种模式可以帮助你在不同的场景下获得最佳效果。</p>
<ol>
<li>基础模型（V3）：快速回答，低门槛的AI助理</li>
<li>
</li>
</ol>
<p>基础模型（V3）可以看作是DeepSeek的基础武器。它不需要勾选，一开始默认就是这个模型。自从去年12月进行升级后，V3的性能得到了大幅提升，甚至可以媲美GPT-4、Claude-3.5等业界顶尖模型。</p>
<p>V3的优势在于它简单、高效、低门槛，特别适合用来解答一些常见的百科类问题。如果你只是想了解某个基本知识点，或者需要一个快速的文本生成，V3绝对能轻松应对。</p>
<p>比如，你想知道“什么是量子力学”，V3可以给你一个简洁、准确的回答。无需太多复杂推理，它的最大优势就是“快”和“准”。</p>
<ol start="2">
<li>深度思考（R1）：推理高手，复杂问题的解题神器<br />
R1是DeepSeek的深度思考模型，专为那些需要复杂推理、深度分析的问题设计。比如，涉及数理逻辑推理、编程代码分析等任务时，R1的表现就非常出色。</li>
</ol>
<p>R1的参数达到了660B，采用了强化学习（RL）和后训练方法，这使得它能够从多个维度进行分析，给出经过精密推理的解决方案。它更像是一个专家型AI，不仅能给出结论，还能清晰地解释每一步的思路。</p>
<p>例如，当你询问一个编程问题时，R1能够为你提供具体的代码实现、优化方案，甚至详细的错误分析。R1的“深度”就是它的强大所在，如果你有复杂问题需要解决，R1绝对是你的不二之选。</p>
<ol start="3">
<li>联网搜索：实时获取最新信息，回答不仅限于知识库<br />
联网搜索模式是DeepSeek的亮点之一，它依赖于RAG（检索增强生成）技术。这意味着，DeepSeek不仅仅依赖自己的知识库，还能从互联网上实时检索到最新的信息来回答问题。</li>
</ol>
<p>这样一来，DeepSeek不仅能回答2024年7月之前的问题，还能根据网络上的新信息，回答时效性更强的问题。它会把最新的新闻、技术动态、甚至社交平台的热议话题带入你的答案中，增强了回答的实用性和准确性。</p>
<p>例如，你问DeepSeek：“2025年春晚有哪些节目？”DeepSeek就能通过联网搜索为你找到最相关的资料，并给出最新的节目安排。</p>
<p>二、与GPT对标：DeepSeek如何成为最强竞争者？<br />
DeepSeek的三个核心模式，不仅仅是一个工具，而是与行业内其他顶级模型直接对标。它的这些对标优势，能帮助你做出更明智的选择。</p>
<ol>
<li>V3对标GPT-4：快速、简洁的“百科全书”<br />
V3和GPT-4是直接竞争的对象。V3采用了Moe架构，拥有671B参数，能够快速响应并提供高效的答案，特别是在百科类问题上，性能非常接近GPT-4。无论你是需要了解某个历史事件，还是快速处理一个简单的文本生成任务，V3都能做到高效且精准。</li>
<li>R1对标o1：推理领域的高手<br />
R1和OpenAI的o1模型很相似，但R1在推理和深度分析上表现得更为出色。R1的660B参数，配合强化学习技术，能够在复杂问题的处理上，提供更深入的分析和更高精度的答案。它的推理能力甚至超越了o1模型，尤其在逻辑推理和复杂问题的解析上，R1无疑更胜一筹。</li>
</ol>
<p>三、如何让DeepSeek充分发挥它的潜力？<br />
要充分利用DeepSeek的强大功能，技巧比工具本身更重要。下面是一些技巧，帮助你用最简单的方式，获得最精准的答案。</p>
<ol>
<li>不需要复杂提示词，简洁明了就是最好的<br />
很多AI使用者总爱准备复杂的提示词模板，但在DeepSeek面前，你根本不需要这么麻烦。你只需用简单的、直白的语言描述需求，它就能精准理解并给出答案。</li>
</ol>
<p>比如，如果你需要一段蛇年拜年祝福语，直接告诉它：“帮我写一段蛇年拜年祝福语”，DeepSeek立马就能生成多个版本供你选择。</p>
<p>这里有一个关键点：与DeepSeek的对话越接地气，结果越精准。所以，别刻意使用太过正式的语言，越简单、越自然，它能理解得越清楚。</p>
<ol start="2">
<li>“小学生”沟通技巧：让AI说人话<br />
有时，DeepSeek的回答可能会让你觉得过于抽象。这时，可以通过“小学生”沟通技巧来解决。你可以给它一个提示：“请用小学生能听懂的话解释什么是大模型。”</li>
<li>
</li>
<li>
</li>
</ol>
<p>这种方法会让DeepSeek用更通俗易懂的语言来回应你，避免那些“八股文”式的官方回答。</p>
<ol start="3">
<li>
<p>持续追问，让问题更清晰<br />
如果你对一个复杂问题不够理解，不妨通过持续追问来深入挖掘更多细节。比如你问：“如何写好提示词？”然后根据答案继续追问，逐步挖掘出具体的步骤和技巧，最后整理成清单格式。</p>
<p>这种方法能够帮助你更加全面、系统地了解一个复杂的概念或操作，让你对问题有更深入的理解。</p>
<ol start="4">
<li>联网搜索：快速了解时事热点<br />
联网搜索是DeepSeek的秘密武器之一，利用它可以随时获取最新的互联网信息。如果你有一些关于新兴技术、最新新闻的疑问，DeepSeek都能为你提供实时的答案。就算是一些2024年7月之后的事件，它也能通过联网搜索得到最准确的回答。</li>
</ol>
<p>当然，网络安全问题时有发生，最近由于国外网络攻击，DeepSeek的联网搜索暂时不可用，但这绝对是它的一大亮点，等恢复后，你可以轻松获取最新信息。</p>
</li>
<li>
<h4>5. 上传附件：让DeepSeek处理你的私密资料</h4>
</li>
</ol>
<p>DeepSeek还支持上传附件功能，最大支持上传50个文件，每个文件最大100MB。你可以上传自己的知识库、文档，甚至一些需要深度分析的材料，让DeepSeek基于这些内容进行分析和推理。</p>
<h4>6. R1的透明度：深度理解推理过程</h4>
<p>R1模型的思维链完全开放，用户可以看到推理过程的每一步。通过这种方式，你不仅仅能看到最终答案，还能理解AI是如何得出这个结论的。这种</p>
<p>开放性极大提升了用户对AI思维的理解，也让AI变得更加可信。</p>]]></description>
    <pubDate>Wed, 05 Mar 2025 21:39:25 +0800</pubDate>
    <dc:creator>neal</dc:creator>
    <guid>https://top.zhongtongzttb.com.cn/?post=45</guid>
</item>
<item>
    <title>DeepSeek使用教程(进阶)</title>
    <link>https://top.zhongtongzttb.com.cn/?post=44</link>
    <description><![CDATA[<p>引言<br />
DeepSeek，最近是真的火！AI圈、科技博主、职场人，甚至连朋友圈的宝妈群都在聊——“DeepSeek太强了！”“国产GPT之光！”“中文能力碾压！”但你真的会用吗？</p>
<p>不少人兴冲冲注册，结果一上来就开始硬憋提示词，仿佛回到了写命令代码的时代，生怕AI听不懂。有人翻着各种“终极提示词秘籍”，一遍遍优化措辞，“请用批判性思维分析……”“请结合苏格拉底式提问法……”结果AI还是答非所问，气得摔键盘。</p>
<p>别折腾了！DeepSeek压根不需要这么复杂的“暗号”，它就喜欢“人话”！你正常说话，它比谁都懂。甚至只要一句“给我讲讲这个”，它都能瞬间进入最佳状态。</p>
<p>这篇文章，给你个DeepSeek的高效使用技巧，彻底摆脱提示词焦虑，让AI真正成为你的“最强大脑”！</p>
<p>一、彻底抛弃提示词模板，DeepSeek更爱“人话”<br />
很多人用DeepSeek，总觉得要写得“专业”一点，生怕AI不明白自己想要什么，结果提示词一写就是半张A4纸，生怕AI智商不够，得“培训”它一下。</p>
<p>但其实，DeepSeek压根不吃这套，它比你想象中聪明得多，根本不需要你拿“套路”教它做人。真正高效的提示词就一条原则：用人话！</p>
<p>最简单的万能公式——你是谁 + 背景 + 你的目标，直接说出需求，DeepSeek能给你最精准的回答。</p>
<p>反面例子：<br />
❌ “你是一个精通心理学的专家，现在请结合马斯洛需求层次理论，帮助我分析一个年轻人选择在大城市工作的心理动机，并用专业术语阐述。”</p>
<p>太啰嗦，AI当然能回答，但它会照本宣科，给你一堆教科书般的废话。</p>
<p>正确做法：<br />
✅ “我25岁，在北京工作，但总觉得压力很大，想回老家又有点不甘心。能不能帮我分析一下，这是不是正常的心理？”</p>
<p>二、输出晦涩难懂？一句“我是小学生”让AI秒变贴心讲解员<br />
很多人吐槽DeepSeek回答太学术，明明就想问个简单问题，结果AI一本正经地整出一篇论文，让人看了头疼。但问题不是AI太高冷，而是你没告诉它“用人话”说！</p>
<p>秘诀很简单：自降身份，让AI别端着。直接在开头加一句“我是小学生”，或者更具体点，比如“请用大白话解释”，AI的输出立马变得接地气。</p>
<p>错误示范：<br />
❌ “请介绍一下区块链的工作原理。”DeepSeek可能会给你来一段“去中心化分布式账本共识机制”的专业解读，看着就累。</p>
<p>正确打开方式：<br />
✅ “我是个完全不懂区块链的小白，你能不能用最简单的比喻，告诉我它是怎么回事？”这时候AI的回答会变成：“区块链就像一本大家都能看的记账本，每个人记的账都一样，谁都改不了。”一下子就懂了吧？</p>
<p>三、DeepSeek的中文写作能力，远超你的想象<br />
DeepSeek的中文写作能力，可能比你想象的还要狠！无论是文艺煽情、犀利讽刺，还是知乎大V式的知识输出，它统统能拿捏。关键是，你得告诉它怎么写！</p>
<p>进阶玩家：<br />
✅ “用王小波的幽默风格，写一个社恐男生暗恋女神的故事。” 结果，DeepSeek一出手，分分钟让你怀疑王小波穿越了。</p>
<p>四、如何让DeepSeek思考得更深？深度思考万能提示词<br />
很多人用DeepSeek，就是丢个问题，等着AI端上答案。但AI不是搜索引擎，真正的价值在于推理，而不仅仅是列清单！想让DeepSeek思考更深入？这句万能提示词送给你：</p>
<p>“请在你的思考分析过程中进行批判性思考、同时反面考虑你的回答，并且要对回答进行多次深入复盘，务必详尽。”</p>
<p>五、DeepSeek的3个使用禁区，别踩坑！<br />
DeepSeek再强，也有三个“雷区”，踩了只会徒增烦恼！</p>
<p>长文杀手？4000字以上逻辑容易崩！<br />
DeepSeek写短文是高手，但让它写部4000字的深度长文？你可能会看到前后矛盾、自我打脸的内容。想写长篇大论？Claude 200K更适合。</p>
<p>敏感内容？一键蒸发！<br />
DeepSeek有后置审核机制，可能刚生成的内容还在，过几秒就突然“蒸发”。破解方法？改提问、多点几次复制按钮，甚至换个AI（GPT-4、Claude）试试。</p>
<p>个人风格？别太指望<br />
DeepSeek擅长结构化写作、模仿名家文风，但要写出100%符合你个人风格的文章？还是要自己润色，AI是工具，不是你的文笔外挂！</p>]]></description>
    <pubDate>Tue, 04 Mar 2025 16:39:02 +0800</pubDate>
    <dc:creator>neal</dc:creator>
    <guid>https://top.zhongtongzttb.com.cn/?post=44</guid>
</item>
<item>
    <title>DeepSeek 使用的技巧</title>
    <link>https://top.zhongtongzttb.com.cn/?post=43</link>
    <description><![CDATA[<p>在人工智能快速发展的时代，DeepSeek 凭借强大的语言处理能力，为我们的工作、学习和生活带来了诸多便利。初次接触的小伙伴们可能会疑惑，如何快速上手并充分发挥其优势呢？别担心，这篇文章将为你详细讲解每一步操作及其关联工具，助你轻松驾驭 DeepSeek。<br />
一、前期准备<br />
（一）注册与登录<br />
操作步骤：打开 DeepSeek 官方网站（建议使用 Chrome、Firefox 等主流浏览器，以获得最佳体验）。在首页找到 “注册” 按钮，有两种注册方式：一是使用手机号注册，输入手机号后，系统会发送验证码，填写验证码并设置密码即可完成注册；二是直接用微信扫码快速登录，方便快捷。<br />
关联工具：主要用到浏览器，记得将其更新到最新版本，防止出现兼容性问题。</p>
<p>（二）熟悉界面布局<br />
操作步骤：登录成功后，进入 DeepSeek 主界面。界面顶部是菜单栏，包含新建对话、历史记录、个人设置等选项；中间是对话输入框和输出区域，你在输入框输入问题或指令，DeepSeek 会在输出区域给出回答；底部可能2. 有快捷功能按钮，比如切换模式、查看帮助文档等。<br />
关联工具：这一步主要是熟悉 DeepSeek 自身界面，无需额外工具。<br />
二、选择合适的模式<br />
（一）新手模式选择<br />
操作步骤：首次使用的话，点击 “新建对话”，在弹出的模式选择框中，选择 “新手引导模式” 或 “基础模式”。这些模式会提供简单的模板和引导话术，帮助你快速了解 DeepSeek 的基本功能和提问方式。例如在新媒体写作场景下，选择 “新媒体写作” 模板，系统会生成包含开头、正文、结尾框架的写作模板，你只需按提示填入关键信息。<br />
关联工具：主要依赖 DeepSeek 自身的模式设置功能，无需外部工具。<br />
（二）专业模式探索<br />
操作步骤：对 DeepSeek 有一定了解后，可尝试切换到 “高级模式” 或 “专业模式”。在这些模式下，你能输入更复杂的指令，实现更精准的需求。比如在学术研究时，输入 “请梳理量子计算在金融领域应用的研究现状，列出近五年重要文献及核心观点，并对比不同研究方法的优劣”，DeepSeek 能给出更专业、深入的分析。<br />
关联工具：主要是掌握 DeepSeek 的指令输入技巧，无需特定外部工具。<br />
三、编写高效提示词<br />
（一）明确需求与指令结构<br />
操作步骤：在输入框输入提示词时，要明确自己的需求。一个完整的指令通常包含主题、目标、要求等要素。比如 “请帮我写一篇关于健康饮食的科普文章，目标读者是中老年人，要求语言通俗易懂，包含常见食物的营养成分介绍和合理搭配建议”。<br />
关联工具：可以使用文本编辑工具，如 Windows 自带的记事本、Mac 的备忘录等，先梳理好需求，再复制粘贴到 DeepSeek 输入框，避免输入错误或遗漏关键信息。<br />
（二）参考提示词库<br />
操作步骤：如果不知道如何编写提示词，可以在网上搜索 “DeepSeek 提示词库”，找到一些公开的优秀提示词示例。比如在文案创作中，参考 “请以 [产品名称] 为例，创作一段朋友圈推广文案，突出产品的 [核心卖点]，语言风格幽默风趣，能吸引年轻消费者” 这样的模板，结合自己的产品信息进行修改。<br />
关联工具：使用浏览器搜索提示词库，一些在线文档平台，如百度文库、豆丁网等，可能有相关资源。<br />
四、内容生成与优化<br />
（一）生成内容<br />
操作步骤：输入提示词后，点击 “发送” 或 “生成” 按钮，DeepSeek 会根据指令生成内容。等待过程中，注意观察进度条，生成时间根据内容复杂程度而定，简单指令可能几秒完成，复杂的研究报告等可能需要更长时间。<br />
关联工具：主要依赖 DeepSeek 的运算和生成能力，无需外部工具。<br />
（二）优化内容<br />
操作步骤：<br />
篇幅调整：如果生成的内容过长或过短，使用 DeepSeek 自带的 “扩写”“精简” 功能。比如点击 “扩写这段内容，增加一些案例和细节”，或 “精简这段文字，去除冗余表述”。<br />
语言优化：对于口语化或表述不准确的地方，点击 “改写” 按钮，让 DeepSeek 优化语言，使其更正式、专业或符合特定风格。<br />
内容丰富：输入 “请补充相关数据”“添加一些实际案例” 等指令，让内容更具说服力和可读性。<br />
关联工具：可以使用 Grammarly 辅助检查语法错误和拼写错误。将 DeepSeek 生成的内容复制到 Grammarly 中，它会实时检测并给出修改建议，提升内容质量。<br />
五、多场景应用与协作<br />
（一）多场景应用<br />
操作步骤：在不同场景下灵活运用 DeepSeek。工作中撰写项目策划书时，输入 “为 [项目名称] 制定一份详细的项目策划书，包括项目背景、目标、执行步骤、预算分配和风险评估”；学习中准备考试复习资料时，输入 “帮我总结 [学科名称][章节名称] 的重点知识点，制作思维导图大纲”。<br />
关联工具：在项目管理场景中，可以结合 Trello 进行任务管理。将 DeepSeek 生成的项目计划任务添加到 Trello 中，通过 Trello 的卡片和列表形式，直观跟踪任务进度，设置截止日期和提醒等。<br />
（二）协作分享<br />
操作步骤：如果需要与团队成员协作，可以使用 DeepSeek 的分享功能。点击 “分享” 按钮，生成分享链接或二维码，将内容分享给同事、同学等。对方点击链接即可查看生成的内容，还能在评论区提出修改建议和意见。<br />
关联工具：配合飞书多维表格进行内容协作管理。将 DeepSeek 生成的内容相关信息，如文章主题、创作进度、负责人等，记录在飞书多维表格中，团队成员可以实时同步信息，共同推进内容创作或项目进展。<br />
通过以上步骤和关联工具的配合使用，相信你已经能熟练使用 DeepSeek，在各个领域发挥其强大功能，提高工作、学习和创作效率。快行动起来，开启你的 DeepSeek 高效之旅吧！</p>]]></description>
    <pubDate>Mon, 03 Mar 2025 19:49:48 +0800</pubDate>
    <dc:creator>neal</dc:creator>
    <guid>https://top.zhongtongzttb.com.cn/?post=43</guid>
</item>
<item>
    <title>DeepSeek使用指南（了解）</title>
    <link>https://top.zhongtongzttb.com.cn/?post=42</link>
    <description><![CDATA[<p>“ 在AI工具井喷的2025年，DeepSeek凭借其强大的中文理解能力和场景化解决方案，成为职场人、创作者和开发者的效率神器。本文将手把手教你解锁DeepSeek的全部潜能，让你的生产力实现指数级飞跃。”</p>
<p>DeepSeek R1正式入驻Azure AI Studio，成为首个直连全球GPU资源池的中国大模型。这记重拳直接击碎&quot;东西方AI生态隔离&quot;的幻想——当华盛顿还在讨论技术封锁法案时，中国AI已用代码轰开微软帝国的大门，聪明的中国用户早已用DeepSeek写完周报、搞定投标书、甚至生成年会相声剧本。</p>
<p>今天给大家介绍一下DeepSeek到底该如何使用，让大家更快的掌握DeekSeek使用方法。</p>
<p>1、跨文档处理</p>
<p>同时上传PDF+Excel+网页链接，输入：</p>
<p>“对比三份材料中的2024营销预算差异，用颜色标注矛盾点”</p>
<p>2、AI翻译官模式</p>
<p>输入：“将下方合同译为英文，保留法律术语准确性，用Markdown标注重点条款”</p>
<p>3、私人知识库</p>
<p>在控制台上传企业手册/产品文档</p>
<p>提问：“根据Q4技术白皮书，列举三项竞品不具备的核心优势”</p>
<p>4、代码生成优化</p>
<p>输入：“写Python爬虫抓取微博热搜，每小时自动去重存储到MySQL，附加异常处理模块”</p>
<p>5、学术研究神器</p>
<p>输入：“用APA格式综述近三年AIGC伦理研究，标注中英文文献比例”</p>
<p>追加：“制作文献演进时间轴，突出中美学派分歧点”</p>
<p>6、文风克隆术</p>
<p>输入：“模仿《舌尖上的中国》解说词风格，描写武汉热干面的制作过程”。</p>]]></description>
    <pubDate>Mon, 03 Mar 2025 19:16:24 +0800</pubDate>
    <dc:creator>neal</dc:creator>
    <guid>https://top.zhongtongzttb.com.cn/?post=42</guid>
</item>
<item>
    <title>DeepSeek超详细使用教程：从入门到精通</title>
    <link>https://top.zhongtongzttb.com.cn/?post=40</link>
    <description><![CDATA[<p>一、初识DeepSeek：AI界的&quot;东方力量&quot;<br />
作为全球最快突破3000万日活用户的AI应用，DeepSeek凭借其强大的推理能力和超高性价比（API成本仅为竞品1/3</p>
<p>），已成为办公、学习、编程等场景的必备工具。其最新R1满血版支持128K长文本处理，生成速度达60 TPS，堪称效率神器。</p>
<p>二、快速上手指南</p>
<ol>
<li>访问入口<br />
网页端：DeepSeek官网 或 官网平替<br />
手机端：应用商店搜索&quot;DeepSeek&quot;（认准蓝色鲸鱼LOGO）<br />
API调用：开发者平台</li>
<li>注册登录</li>
</ol>
<h1>注册流程演示</h1>
<ol>
<li>点击右上角「笑脸图标」</li>
<li>选择「邮箱/手机注册」</li>
<li>接收验证码完成认证</li>
<li>设置高强度密码（建议含大小写+数字）<br />
三、核心功能详解</li>
<li>智能对话<br />
黄金提问公式：背景 + 任务 + 要求 + 补充</li>
</ol>
<p>示例：<br />
【背景】我是新媒体运营新人<br />
【任务】需要撰写公众号推文<br />
【要求】语言活泼，带emoji表情<br />
【补充】产品是智能咖啡机，目标用户是都市白领</p>
<ol start="2">
<li>文件处理<br />
支持PDF/Word/Txt上传，三大神级指令：</li>
</ol>
<p>/总结：提取文档核心观点<br />
/对比：分析多文档差异<br />
/制表：将条款转为表格</p>
<ol start="3">
<li>代码生成</li>
</ol>
<h1>生成爱心图案代码（带进度条）</h1>
<p>import requests<br />
from tqdm import tqdm</p>
<p>def download_image(url, save_path):<br />
response = requests.get(url, stream=True)<br />
total_size = int(response.headers.get('content-length', 0))</p>
<pre><code>with open(save_path, 'wb') as f, tqdm(
    desc=save_path,
    total=total_size,
    unit='iB',
    unit_scale=True
) as bar:
    for data in response.iter_content(chunk_size=1024):
        size = f.write(data)
        bar.update(size)</code></pre>
<p>提示：输入&quot;/注释&quot;可让AI解释代码逻辑</p>
<p>四、高阶使用技巧</p>
<ol>
<li>深度思考模式<br />
勾选输入框旁的「深度思考」开关</li>
</ol>
<p>，AI会展示完整推理过程：</p>
<p>用户问题 → 意图分析 → 知识检索 → 方案生成 → 效果预判</p>
<ol start="2">
<li>魔法指令集<br />
指令  功能  示例<br />
/续写 继续未完成内容 适合长文创作中断时使用<br />
/简化 复杂内容转大白话    解读专业报告<br />
/示例 生成带案例的解决方案  营销方案设计<br />
/检查 排查文档错误  合同条款审核</li>
<li>本地部署方案<br />
通过Ollama工具实现：</li>
</ol>
<h1>安装部署命令</h1>
<p>ollama run deepseek-r1:32b  # 32B参数版需24G显存<br />
ollama run deepseek-r1:8b   # 8B参数版适配家用显卡<a href="@ref">9</a><br />
五、应用场景案例</p>
<ol>
<li>职场效率提升<br />
会议纪要：自动生成带重点标记的摘要<br />
数据分析：上传Excel自动生成可视化报告<br />
邮件撰写：输入&quot;/正式&quot;切换商务语气</li>
<li>学习研究助手<br />
论文阅读：上传PDF自动生成综述报告<br />
解题辅导：展示分步推导过程（数学题准确率79.8%）<br />
语言学习：实时翻译支持338种编程语言<br />
六、避坑指南<br />
警惕&quot;10万元本地部署教程&quot;，官方声明从未授权收费服务<br />
超过50页文档建议先拆分处理，避免解析失败<br />
手机端卡顿时可切换「纳米AI」使用满血版<br />
重要内容务必人工复核，AI可能产生幻觉</li>
</ol>]]></description>
    <pubDate>Thu, 20 Feb 2025 19:47:54 +0800</pubDate>
    <dc:creator>neal1988</dc:creator>
    <guid>https://top.zhongtongzttb.com.cn/?post=40</guid>
</item>
<item>
    <title>Python爬虫实战</title>
    <link>https://top.zhongtongzttb.com.cn/?post=27</link>
    <description><![CDATA[<p>使用BeautifulSoup和scrapy抓取网页数据</p>
<p>在当今信息爆炸的时代，数据无处不在，如何有效地抓取、处理和分析这些数据成为了许多开发者的必修课。本篇博客将深入探讨如何使用Python中的两个强大工具：BeautifulSoup和Scrapy来抓取网页数据。我们将从基础知识开始，逐步深入到实际应用，最终实现一个完整的爬虫项目。</p>
<h3>1. 什么是爬虫？</h3>
<p>网络爬虫（Web Crawler）是一种自动访问互联网并提取信息的程序。它可以帮助我们从网站上获取大量数据，进行分析和处理。爬虫的应用非常广泛，比如搜索引擎、数据分析、市场调研等。</p>
<h3>2. 准备工作</h3>
<p>在开始之前，我们需要确保已经安装了Python及其相关库。可以使用pip进行安装：</p>
<pre><code class="language-bash">pip install requests beautifulsoup4 scrapy</code></pre>
<pre><code class="language-bash">pip install requests beautifulsoup4 scrapy</code></pre>
<pre><code class="language-bash">pip install requests beautifulsoup4 scrapy</code></pre>
<pre><code class="language-bash">pip install requests beautifulsoup4 scrapy</code></pre>
<ul>
<li><strong>requests</strong>：用于发送网络请求。</li>
<li><strong>beautifulsoup4</strong>：用于解析HTML和XML文档。</li>
<li><strong>scrapy</strong>：一个强大的网络爬虫框架。</li>
</ul>
<h3>3. 使用BeautifulSoup抓取网页数据</h3>
<h4>3.1. BeautifulSoup简介</h4>
<p>BeautifulSoup是一个用于解析HTML和XML的Python库。它可以将复杂的网页结构转化为一个易于操作的树形结构，使得我们能够轻松提取网页中的信息。</p>
<h4>3.2. 示例：抓取豆瓣电影排行榜</h4>
<p>在这个示例中，我们将抓取豆瓣电影排行榜的前10部电影及其评分。</p>
<h5>3.2.1. 发送请求</h5>
<p>首先，我们需要发送一个HTTP请求来获取网页的HTML内容。</p>
<pre><code class="language-python">import requests
from bs4 import BeautifulSoup

url = 'https://movie.douban.com/chart'
response = requests.get(url)
html_content = response.text</code></pre>
<pre><code class="language-python">import requests
from bs4 import BeautifulSoup

url = 'https://movie.douban.com/chart'
response = requests.get(url)
html_content = response.text</code></pre>
<pre><code class="language-python">import requests
from bs4 import BeautifulSoup

url = 'https://movie.douban.com/chart'
response = requests.get(url)
html_content = response.text</code></pre>
<pre><code class="language-python">import requests
from bs4 import BeautifulSoup

url = 'https://movie.douban.com/chart'
response = requests.get(url)
html_content = response.text</code></pre>
<h5>3.2.2. 解析HTML</h5>
<p>接下来，我们使用BeautifulSoup来解析HTML内容。</p>
<pre><code class="language-python">soup = BeautifulSoup(html_content, 'html.parser')</code></pre>
<pre><code class="language-python">soup = BeautifulSoup(html_content, 'html.parser')</code></pre>
<pre><code class="language-python">soup = BeautifulSoup(html_content, 'html.parser')</code></pre>
<pre><code class="language-python">soup = BeautifulSoup(html_content, 'html.parser')</code></pre>
<h5>3.2.3. 提取数据</h5>
<p>我们将查找电影标题和评分，并将结果存储在一个列表中。</p>
<pre><code class="language-python">movies = []

for item in soup.select('.item'):
    title = item.select_one('.title').text
    rating = item.select_one('.rating_num').text
    movies.append({'title': title, 'rating': rating})

print(movies)</code></pre>
<pre><code class="language-python">movies = []

for item in soup.select('.item'):
    title = item.select_one('.title').text
    rating = item.select_one('.rating_num').text
    movies.append({'title': title, 'rating': rating})

print(movies)</code></pre>
<pre><code class="language-python">movies = []

for item in soup.select('.item'):
    title = item.select_one('.title').text
    rating = item.select_one('.rating_num').text
    movies.append({'title': title, 'rating': rating})

print(movies)</code></pre>
<pre><code class="language-python">movies = []

for item in soup.select('.item'):
    title = item.select_one('.title').text
    rating = item.select_one('.rating_num').text
    movies.append({'title': title, 'rating': rating})

print(movies)</code></pre>
<h4>3.3. 完整代码</h4>
<p>将上述代码整合成一个完整的爬虫程序：</p>
<pre><code class="language-python">import requests
from bs4 import BeautifulSoup

def get_movies():
    url = 'https://movie.douban.com/chart'
    response = requests.get(url)
    soup = BeautifulSoup(response.text, 'html.parser')
    movies = []

    for item in soup.select('.item'):
        title = item.select_one('.title').text
        rating = item.select_one('.rating_num').text
        movies.append({'title': title, 'rating': rating})

    return movies

if __name__ == '__main__':
    movie_list = get_movies()
    for movie in movie_list:
        print(movie)</code></pre>
<pre><code class="language-python">import requests
from bs4 import BeautifulSoup

def get_movies():
    url = 'https://movie.douban.com/chart'
    response = requests.get(url)
    soup = BeautifulSoup(response.text, 'html.parser')
    movies = []

    for item in soup.select('.item'):
        title = item.select_one('.title').text
        rating = item.select_one('.rating_num').text
        movies.append({'title': title, 'rating': rating})

    return movies

if __name__ == '__main__':
    movie_list = get_movies()
    for movie in movie_list:
        print(movie)</code></pre>
<pre><code class="language-python">import requests
from bs4 import BeautifulSoup

def get_movies():
    url = 'https://movie.douban.com/chart'
    response = requests.get(url)
    soup = BeautifulSoup(response.text, 'html.parser')
    movies = []

    for item in soup.select('.item'):
        title = item.select_one('.title').text
        rating = item.select_one('.rating_num').text
        movies.append({'title': title, 'rating': rating})

    return movies

if __name__ == '__main__':
    movie_list = get_movies()
    for movie in movie_list:
        print(movie)</code></pre>
<pre><code class="language-python">import requests
from bs4 import BeautifulSoup

def get_movies():
    url = 'https://movie.douban.com/chart'
    response = requests.get(url)
    soup = BeautifulSoup(response.text, 'html.parser')
    movies = []

    for item in soup.select('.item'):
        title = item.select_one('.title').text
        rating = item.select_one('.rating_num').text
        movies.append({'title': title, 'rating': rating})

    return movies

if __name__ == '__main__':
    movie_list = get_movies()
    for movie in movie_list:
        print(movie)</code></pre>
<h3>4. 使用Scrapy抓取网页数据</h3>
<h4>4.1. Scrapy简介</h4>
<p>Scrapy是一个功能强大的爬虫框架，适合进行大规模数据抓取和处理。它提供了许多高级特性，如异步处理、请求调度和数据管道等。</p>
<h4>4.2. 创建Scrapy项目</h4>
<p>我们可以使用Scrapy<strong>命令行工具</strong>创建一个新的<a href="https://so.csdn.net/so/search?q=%E7%88%AC%E8%99%AB%E9%A1%B9%E7%9B%AE&amp;spm=1001.2101.3001.7020">爬虫项目</a>：</p>
<pre><code class="language-bash">scrapy startproject douban_movies</code></pre>
<pre><code class="language-bash">scrapy startproject douban_movies</code></pre>
<pre><code class="language-bash">scrapy startproject douban_movies</code></pre>
<pre><code class="language-bash">scrapy startproject douban_movies</code></pre>
<p>这将创建一个名为 <code>douban_movies</code>的文件夹，里面包含项目的基本结构。</p>
<h4>4.3. 编写爬虫</h4>
<p>在项目中，我们需要创建一个新的爬虫文件，比如 <code>douban.py</code>，并实现爬虫的逻辑。</p>
<h5>4.3.1. 编写爬虫代码</h5>
<p>在 <code>spiders</code>目录下创建 <code>douban.py</code>文件，内容如下：</p>
<pre><code class="language-python">import scrapy

class DoubanSpider(scrapy.Spider):
    name = 'douban'
    start_urls = ['https://movie.douban.com/chart']

    def parse(self, response):
        for item in response.css('.item'):
            yield {
                'title': item.css('.title::text').get(),
                'rating': item.css('.rating_num::text').get(),
            }</code></pre>
<pre><code class="language-python">import scrapy

class DoubanSpider(scrapy.Spider):
    name = 'douban'
    start_urls = ['https://movie.douban.com/chart']

    def parse(self, response):
        for item in response.css('.item'):
            yield {
                'title': item.css('.title::text').get(),
                'rating': item.css('.rating_num::text').get(),
            }</code></pre>
<pre><code class="language-python">import scrapy

class DoubanSpider(scrapy.Spider):
    name = 'douban'
    start_urls = ['https://movie.douban.com/chart']

    def parse(self, response):
        for item in response.css('.item'):
            yield {
                'title': item.css('.title::text').get(),
                'rating': item.css('.rating_num::text').get(),
            }</code></pre>
<pre><code class="language-python">import scrapy

class DoubanSpider(scrapy.Spider):
    name = 'douban'
    start_urls = ['https://movie.douban.com/chart']

    def parse(self, response):
        for item in response.css('.item'):
            yield {
                'title': item.css('.title::text').get(),
                'rating': item.css('.rating_num::text').get(),
            }</code></pre>
<h4>4.4. 运行爬虫</h4>
<p>我们可以通过以下命令运行爬虫，并将结果保存到JSON文件中：</p>
<pre><code class="language-bash">scrapy crawl douban -o movies.json</code></pre>
<pre><code class="language-bash">scrapy crawl douban -o movies.json</code></pre>
<pre><code class="language-bash">scrapy crawl douban -o movies.json</code></pre>
<pre><code class="language-bash">scrapy crawl douban -o movies.json</code></pre>
<h3>5. 数据存储</h3>
<p>在爬虫抓取数据后，我们通常需要将数据存储到数据库或文件中。Scrapy提供了数据管道（Item Pipeline）来处理数据存储。我们可以在 <code>settings.py</code>中配置管道，使用<strong>SQLite</strong>或MongoDB等数据库进行存储。</p>
<h3>6. 处理反爬虫机制</h3>
<p>许多网站都有反爬虫机制，比如IP封禁、用户代理检查等。我们可以通过以下方式来绕过这些限制：</p>
<h4>6.1. 设置用户代理</h4>
<p>在Scrapy的设置中，我们可以自定义用户代理：</p>
<pre><code class="language-python">USER_AGENT = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36'
1'运行运行</code></pre>
<pre><code class="language-python">USER_AGENT = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36'
1'运行运行</code></pre>
<pre><code class="language-python">USER_AGENT = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36'
1'运行运行</code></pre>
<pre><code class="language-python">USER_AGENT = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36'
1'运行运行</code></pre>
<h4>6.2. 设置代理IP</h4>
<p>使用代理IP可以有效防止IP封禁，Scrapy也支持在请求中设置代理。</p>
<h3>7. 实践：爬取多个页面</h3>
<p>在实际应用中，我们往往需要爬取多个页面的数据。我们可以在Scrapy中使用 <code>start_requests</code>方法来实现这一点。</p>
<h4>7.1. 修改爬虫代码</h4>
<p>修改 <code>DoubanSpider</code>中的 <code>start_requests</code>方法，实现分页抓取：</p>
<pre><code class="language-python">def start_requests(self):
    for page in range(0, 10):  # 抓取前10页
        yield scrapy.Request(url=f'https://movie.douban.com/chart?start={page * 10}', callback=self.parse)
123'运行运行</code></pre>
<pre><code class="language-python">def start_requests(self):
    for page in range(0, 10):  # 抓取前10页
        yield scrapy.Request(url=f'https://movie.douban.com/chart?start={page * 10}', callback=self.parse)
123'运行运行</code></pre>
<pre><code class="language-python">def start_requests(self):
    for page in range(0, 10):  # 抓取前10页
        yield scrapy.Request(url=f'https://movie.douban.com/chart?start={page * 10}', callback=self.parse)
123'运行运行</code></pre>
<pre><code class="language-python">def start_requests(self):
    for page in range(0, 10):  # 抓取前10页
        yield scrapy.Request(url=f'https://movie.douban.com/chart?start={page * 10}', callback=self.parse)
123'运行运行</code></pre>
<h3>8. 数据清洗和分析</h3>
<p>抓取到的数据往往需要进行清洗和分析。我们可以使用<strong>Pandas</strong>库来处理数据，进行数据清洗、统计分析和可视化等操作。</p>
<h4>8.1. 安装Pandas</h4>
<p>使用以下命令安装Pandas库：</p>
<pre><code class="language-bash">pip install pandas</code></pre>
<pre><code class="language-bash">pip install pandas</code></pre>
<pre><code class="language-bash">pip install pandas</code></pre>
<pre><code class="language-bash">pip install pandas</code></pre>
<h4>8.2. 数据清洗示例</h4>
<p>以下是一个简单的数据清洗示例：</p>
<pre><code class="language-python">import pandas as pd

# 读取抓取的数据
data = pd.read_json('movies.json')

# 数据清洗
data['rating'] = data['rating'].astype(float)  # 将评分转为浮点数
cleaned_data = data.dropna()  # 删除缺失值

# 打印清洗后的数据
print(cleaned_data)</code></pre>
<pre><code class="language-python">import pandas as pd

# 读取抓取的数据
data = pd.read_json('movies.json')

# 数据清洗
data['rating'] = data['rating'].astype(float)  # 将评分转为浮点数
cleaned_data = data.dropna()  # 删除缺失值

# 打印清洗后的数据
print(cleaned_data)</code></pre>
<pre><code class="language-python">import pandas as pd

# 读取抓取的数据
data = pd.read_json('movies.json')

# 数据清洗
data['rating'] = data['rating'].astype(float)  # 将评分转为浮点数
cleaned_data = data.dropna()  # 删除缺失值

# 打印清洗后的数据
print(cleaned_data)</code></pre>
<pre><code class="language-python">import pandas as pd

# 读取抓取的数据
data = pd.read_json('movies.json')

# 数据清洗
data['rating'] = data['rating'].astype(float)  # 将评分转为浮点数
cleaned_data = data.dropna()  # 删除缺失值

# 打印清洗后的数据
print(cleaned_data)</code></pre>
<h3>9. 总结</h3>
<p>通过本文的学习，我们了解了如何使用BeautifulSoup和Scrapy两个强大的工具来抓取网页数据。BeautifulSoup适合快速、小规模的数据抓取，而Scrapy则更适合大规模、复杂的网站抓取。掌握这两种工具可以帮助我们更高效地进行数据获取与分析。</p>
<p>在实际开发中，我们还需注意网站的Robots协议，确保我们的爬虫行为不违反网站的使用条款。此外，反爬虫机制的处理也是爬虫开发中需要重点关注的内容。</p>]]></description>
    <pubDate>Wed, 18 Dec 2024 13:09:01 +0800</pubDate>
    <dc:creator>jm8X08LA</dc:creator>
    <guid>https://top.zhongtongzttb.com.cn/?post=27</guid>
</item>
<item>
    <title>python+requests实现接口测试</title>
    <link>https://top.zhongtongzttb.com.cn/?post=26</link>
    <description><![CDATA[<p>一、requests安装<br />
可以通过控制台输入命令pip install requests安装requests，但是我这里主要介绍pycharm工具中安装requests<br />
一张图解释安装步骤，简单快捷</p>
<p>二、requests常用语法<br />
1、基本请求方法，包含参数传递<br />
（1）get参数传递，示例：</p>
<p>url=“xxxxx”<br />
xx={<br />
&quot;xxx&quot;:&quot;xx&quot;<br />
&quot;xxxxx&quot;:1<br />
}<br />
r=requests.get(url，params=xx)<br />
print(r.text)#解析返回结果并打印出来</p>
<p>（2）post参数传递，示例：</p>
<p>url=“xxxxx”<br />
xx={<br />
&quot;xxx&quot;:&quot;xx&quot;<br />
&quot;xxxxx&quot;:1<br />
}<br />
r=requests.post(url，data=xx)<br />
print(r.text)#解析返回结果并打印出来<br />
print(r.json())#josn格式打印出来，适用于返回是json内容</p>
<p>（3）文件传输，示例：</p>
<p>url=“xxxxx”<br />
data1={<br />
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx<br />
}<br />
filexxxx ={<br />
&quot;filexxxxxxxx&quot;:open('xxx.jpg','rb')#文件内容根据实际路径修改<br />
}<br />
r=requests.get(url，data=data1，files=filexxxx)<br />
print(r.text)#解析返回结果并打印出来</p>
<p>（4）断言，示例：</p>
<p>url=“xxxxx”<br />
xx={<br />
&quot;xxx&quot;:&quot;xx&quot;<br />
&quot;xxxxx&quot;:1<br />
}<br />
r=requests.get(url，params=xx)<br />
print(r.text)#解析返回结果并打印出来<br />
assert r.status_code == 200#断言操作，将响应值与200作对比</p>
<p>（5）获取token值并传入需要用到的地方，示例：</p>
<p>url1 = &quot;<a href="https://xx.xx/xx/xx/2.1.0/token/sign">https://xx.xx/xx/xx/2.1.0/token/sign</a>&quot;<br />
r1=requests.post(url1)<br />
t = r1.json()[&quot;token&quot;]#返回结果是json，只取json（）内容里token值并赋值到t中</p>
<h1>上图可以看出r1.json（）返回的内容还有别的参数</h1>
<p>三、实例</p>
<p>import random<br />
import requests<br />
def test_zhuce():<br />
url = &quot;<a href="https://xx.xx/xx/xx/2.0.0/visitor/insert/user/">https://xx.xx/xx/xx/2.0.0/visitor/insert/user/</a>&quot;<br />
url1 = &quot;<a href="https://xx.xx/xx/xx/2.1.0/token/sign">https://xx.xx/xx/xx/2.1.0/token/sign</a>&quot;<br />
r1=requests.post(url1)<br />
t = r1.json()[&quot;token&quot;]<br />
b=random.randint(1,100000)<br />
date = {<br />
&quot;companyId&quot; : &quot;a9a4828204054088bb520df1e1d5b69f&quot;,<br />
&quot;deadLineTime&quot;: &quot;2020-10-22T16:00:00.000Z&quot;,</p>
<h1>&quot;fields&quot;: &quot;[{\&quot;fieldName\&quot;:\&quot;code\&quot;,\&quot;fieldType\&quot;:9,\&quot;fieldValue\&quot;:\&quot;C:\Users\Administrator\aaaaa.jpg\&quot;,\&quot;fieldId\&quot;:999}]&quot;,</h1>
<p>&quot;groupId&quot;: &quot;aab59cf9edb542e7a2e9e6d415ae311b&quot;,<br />
&quot;headPath&quot;:&quot;/Z&quot;,#照片路径，我这边是直接获取以前上传过的照片路径，取服务器端的值，你可以自己使用文件上传的方式上传你的照片，采用上面的二中的（3）方法<br />
&quot;msToken&quot;: t,<br />
&quot;name&quot;: &quot;接口注册%d&quot;%b,<br />
&quot;propertyId&quot;: &quot;f8ff8ea63c3440eb85b81cbccacddef0&quot;,<br />
&quot;registerType&quot;:1,<br />
&quot;userType&quot;: 2<br />
}</p>
<h1>header = {</h1>
<p>#</p>
<h1>}</h1>
<h1>r2=requests.post(url,files=file)</h1>
<h1>print(r2.json())</h1>
<p>r = requests.post(url, data=date)</p>
<h1>r=requests.post(url)</h1>
<p>print('\n'&quot;状态：&quot;,r.text)<br />
print('\n'&quot;头部信息：&quot;,r.headers)<br />
print('\n'&quot;cookie信息：&quot;,r.cookies)<br />
print('\n'&quot;token信息：&quot;,t)</p>
<h1>assert r.status_code == 200</h1>
<p>运行运行<br />
注意：<br />
当后端返回结果为415状态时，“status”:415,“error”:“Unsupported Media Type”,如下问题：</p>
<p>注意查看代码中的url是否正确，可适当对后面的路径进行删除修改！！！</p>]]></description>
    <pubDate>Tue, 17 Dec 2024 15:23:53 +0800</pubDate>
    <dc:creator>jm8X08LA</dc:creator>
    <guid>https://top.zhongtongzttb.com.cn/?post=26</guid>
</item>
<item>
    <title>7个实用的Python自动化测试框架</title>
    <link>https://top.zhongtongzttb.com.cn/?post=25</link>
    <description><![CDATA[<p>1、Unittest<br />
unittest是Python内置的标准类库。它的API跟Java的JUnit、.net的NUnit，C++的CppUnit很相似。</p>
<p>通过继承unittest.TestCase来创建一个测试用例。</p>
<p>2、 Doctest<br />
doctest 模块会搜索那些看起来像交互式会话的 Python 代码片段，然后尝试执行并验证结果.即使从没接触过 doctest，我们也可以从这个名字中窥到一丝端倪。“它看起来就像代码里的文档字符串（docstring）一样” 如果你这么想的话，就已经对了一半了。</p>
<p>3、pytest<br />
pytest是python的一种单元测试框架，与python自带的unittest测试框架类似，但是比unittest框架使用起来更简洁，效率更高。根据pytest的官方网站介绍，它具有如下特点： ①非常容易上手，入门简单，文档丰富，文档中有很多实例可以参考 ②能够支持简单的单元测试和复杂的功能测试 ③支持参数化 ④执行测试过程中可以将某些测试跳过，或者对某些预期失败的case标记成失败 ⑤支持重复执行失败的case ⑥支持运行由nose, unittest编写的测试case ⑦具有很多第三方插件，并且可以自定义扩展 ⑧方便的和持续集成工具集成</p>
<p>4、Nose<br />
Nose是对unittest的扩展，使得python的测试更加简单。nose自动发现测试代码并执行，nose提供了大量的插件，比如测试输出的xUnitcompatible，覆盖报表等等。</p>
<p>nose的详细文档： <a href="https://nose.readthedocs.org/en/latest/">https://nose.readthedocs.org/en/latest/</a></p>
<p>5、tox<br />
最大的特色，是自动最测试环境的管理以及使用多个解析器配置进行测试。</p>
<p>tox的详细文档： <a href="http://testrun.org/tox/latest/">http://testrun.org/tox/latest/</a></p>
<p>6、Unittest2<br />
是unitest的升级版。对API进行了改善以及更好的诊断语法。</p>
<p>unittest2的详细文档：<a href="https://pypi.python.org/pypi/unittest2">https://pypi.python.org/pypi/unittest2</a></p>
<p>7、mock unittest.<br />
mock是用来测试python的库。在python3.3版本以后，这个是一个标准库。对老版本来说，使用pip install mock进行安装。</p>
<p>mock的精髓在于，你可以使用模拟的对象来替代你的系统的一部分，然后验证后续的执行是否正确。mock的详细文档：<a href="http://www.voidspace.org.uk/python/mock/">http://www.voidspace.org.uk/python/mock/</a></p>
<p>结语<br />
也就是说，如果你对自动化测试有你的期望值，那么就肯定是要付出相应的代价和精力的。好的东西也是需要优秀的人花大量的时间去完成的。在正式进入到自动化测试的领域之前，先要建立这样的价值观才能在软件测试这条路上走的更远。</p>
<p>看完上述内容，你们掌握7个超实用的Python自动化测试框架分别是什么的方法了吗？如果还想学到更多技能或想了解更多相关内容，关注我不迷路哦。</p>]]></description>
    <pubDate>Tue, 17 Dec 2024 12:59:19 +0800</pubDate>
    <dc:creator>jm8X08LA</dc:creator>
    <guid>https://top.zhongtongzttb.com.cn/?post=25</guid>
</item>
<item>
    <title>pytest框架详解</title>
    <link>https://top.zhongtongzttb.com.cn/?post=24</link>
    <description><![CDATA[<p>Pytest框架<br />
介绍<br />
1.简介<br />
pytest是纯python编写的自动化测试框架，可以支持python语法编写测试用例，是一个非常成熟的全功能的Python测试框架。</p>
<p>主要有以下几个特点：</p>
<p>简单灵活，容易上手；<br />
支持参数化；<br />
能够支持简单的单元测试和复杂的功能测试，还可以结合selenium、requests做自动化测试；<br />
pytest具有很多第三方插件，并且可以自定义扩展。<br />
安装：pip install pytest</p>
<p>官方文档：<a href="https://docs.pytest.org">https://docs.pytest.org</a></p>
<p>2.第一个pytest用例<br />
def test<em>01():<br />
assert 1 == 1<br />
3.pytest命名规范<br />
测试模块：以 test</em> 开头命名，如：test_login.py，或以 _test 结尾；</p>
<p>测试类：必须以Test开头命名，且测试类中不能有 <strong>init</strong> 方法；</p>
<p>测试方法/测试函数：必须以test开头。</p>
<p>4.常用参数<br />
可以通过pytest -h来查看所有可用参数。pytest的参数有很多，下面是归纳一些常用的参数：</p>
<p>无参数：读取路径下符合条件的所有类、函数、方法全部执行；<br />
-v：打印详细运行日志；<br />
-s：输出调试信息，包括print打印的信息；命令行输入：pytest -s;<br />
-x：运行用例失败立即停止运行</p>
<p>–maxfail<br />
用例失败数达到某个设定的值停止运行<br />
pytest --maxfail=[num]</p>
<p>-m 运行所有@pytest.mark.[标记名] 标记的用例</p>
<p>比如：用例标记 @pytest.mark.high</p>
<p>pytest -m=hign 或者 pytest -m hign。# 表示只执行有此标记hight的case。</p>
<p>pytest -m=&quot;hign or smoke&quot; 或者 pytest -m &quot;hign or smoke&quot; # 表示两种标记都执行</p>
<p>–reruns=num：失败用例重跑num次。需要安装 pytest-rerunfailures 插件模块。</p>
<p>-n参数，启用多线程或分布式运行测试用例。需要安装pip install pytest-xdist 插件模块。<br />
命令行输入：pytest -vs -n=2</p>
<p>-k： 指定运行某个或某些用例<br />
pytest -k ‘类名’<br />
pytest -k ‘方法名’<br />
pytest -k ‘类名 and not 方法名’ # 运行类里所有方法，不包含某个方法<br />
命令行输入：pytest -vs -k=01</p>
<p>python程序运行pytest：</p>
<p>caseNameString = &quot; or &quot;.join(caseNameList)<br />
cmd = f&quot;python -m pytest -k \&quot;{caseNameString}\&quot; --alluredir ./allure --clean-alluredir&quot;<br />
os.system(cmd)<br />
-k的值支持中文的哟~<br />
参数-n，启用多线程或分布式运行测试用例。需要安装pip install pytest-xdist 插件模块。<br />
命令行输入：pytest -vs -n=2</p>
<p>5.实现数据驱动<br />
Pytest 测试框架的数据驱动是由 pytest 自带的pytest.mark.parametrize()来实现的。</p>
<p>@pytest.mark.parametrize() 装饰器接收两个参数：<br />
第一个参数以字符串的形式存在，它代表能被测试函数所能接受的参数，如果被测试函数有多个参数，则以逗号分隔；<br />
第二个参数用于保存测试数据。如果只有一组数据，以列表的形式存在，如果有多组数据，以列表嵌套元组的形式存在（例如： [1,1]或者[(1,1), (2,2)]）。</p>
<p>实例</p>
<p>class Test01:<br />
@pytest.mark.parametrize('a,b,expect',[(1,1,1),(2,3,5)])<br />
def test_001(self,a,b,expect):<br />
print('测试a+b的结果')<br />
assert a+b==expect</p>
<pre><code>@pytest.mark.parametrize('c,d,expect', [(2, 4, 2), (9, 10, 1)])
def test_002(self,c,d,expect):
    assert d-c==expect</code></pre>
<p>if <strong>name</strong> == '<strong>main</strong>':<br />
pytest.main([<strong>file</strong>, '-k','test_001'])<br />
6.pytest fixtures<br />
6.1 fixture用途</p>
<p>fixture主要用来做初始化环境以及测试结束后的数据清除。<br />
pytest fixture与setup,teardown功能一样，但比之更加灵活，完全可以代替setup,teardown。<br />
6.2 fixture参数详解</p>
<p>@pytest.fixture(scope='function',params=None,autouse=False,ids=None,name=None)<br />
yield</p>
<p>fixture装饰器，相当于setup，测试用例的前置</p>
<ul>
<li>scope: 有四个级别参数'function（默认）'、'class'、'module'、'session'。</li>
<li>params：一个可选的参数列表，列表中每个数据都可以作为用例的输入。也就说有多少数据，就会形成多少用例。可以通过request.param来获取该次调用的参数。</li>
<li>autouse：如果True，自动调用fixture功能。如果为False则需要调用fixture。</li>
<li>ids：每个字符串id的列表，每个字符串对应于params这样他们就是测试ID的一部分。如果没有提供ID它们将从params自动生成。</li>
<li>name：fixture的名称。这默认为装饰函数的名称。如果fixture在定义它的统一模块。<br />
yield：这个关键字之后的代码相当于teardown，测试用例的后置。</li>
</ul>
<p>6.3 fixture的作用范围</p>
<p>fixture里面有个scope参数可以控制fixture的作用范围：session&gt;module&gt;class&gt;function<br />
-function：每一个函数或方法都会调用<br />
-class：每一个类调用一次，一个类中可以有多个方法<br />
-module：每一个.py文件调用一次，该文件内又有多个function和class<br />
-session：是多个文件调用一次，可以跨.py文件调用，每个.py文件就是module</p>
<p>6.4 调用fixture的三种方法</p>
<p>方式1：函数或类里直接传fixture的函数名称</p>
<pre><code>@pytest.fixture()
def test_fixture(self):
    print('\n用例开始执行fix1\n')
    yield
    print('\n用例执行结束fix1\n')

def test_a(self, test_fixture):
    print('runing')
    assert 1 == 1</code></pre>
<p>方式2： 使用装饰器@pytest.mark.usefixtures()修饰需要运行的用例（可以叠加使用多个装饰器）</p>
<pre><code>@pytest.fixture()
def test_fixture(self):
    print('\n用例开始执行fix1\n')
    yield
    print('\n用例执行结束fix1\n')

@pytest.fixture()
def test_fixture2(self):
    print('\n用例开始执行fix2\n')
    yield
    print('\n用例执行结束fix2\n')

@pytest.mark.usefixtures('test_fixture')
@pytest.mark.usefixtures('test_fixture2')
def test_b(self):
    assert 1==1</code></pre>
<p>执行结果</p>
<p>7.skip – 跳过测试<br />
7.1 pytest.skip() 用于函数内，跳过测试用例</p>
<p>@pytest.mark.parametrize('a,b,expect',[(1,1,1),(2,3,5)])<br />
def test_001(self,test1,a,b,expect):<br />
pytest.skip('跳过此测试用例')<br />
assert a+b==expect<br />
用于函数外，跳过测试用例</p>
<p>@pytest.mark.skip(reason=&quot;功能未实现&quot;)<br />
@pytest.mark.parametrize('a,b,expect',[(1,1,1),(2,3,5)])<br />
def test_001(self,test1,a,b,expect):<br />
assert a+b==expect<br />
用在函数外，条件condition为True时，跳过用例</p>
<p>@pytest.mark.skipif(condition=True,reason=&quot;功能未实现&quot;)<br />
@pytest.mark.parametrize('a,b,expect',[(1,1,1),(2,3,5)])<br />
def test_001(self,test1,a,b,expect):<br />
assert a+b==expect</p>
<p>8.rerunfailure–失败重跑，插件pytest-rerunfailures<br />
安装</p>
<p>前提条件： pytest (&gt;=5.3) 和python &gt;=3.6<br />
安装：pip install pytest-rerunfailures<br />
查看安装版本：pip show pytest-rerunfailures<br />
pytest-rerunfailures 使用</p>
<p>命令行参数： --reruns n（重新运行次数）–reruns-delay m（等待运行秒数）<br />
使用装饰器： @pytest.mark.flaky(reruns=5, reruns_delay=2)<br />
命令行实例</p>
<h1>!/usr/bin/env python3</h1>
<h1>!coding:utf-8</h1>
<p>import pytest<br />
import random</p>
<p>def test_simple_assume():</p>
<h1>每次case运行的值为1或者2，具有随机性</h1>
<p>r = random.randint(1, 3)<br />
assert r == 1</p>
<p>if <strong>name</strong> == '<strong>main</strong>':<br />
pytest.main(['Test_demo01.py', '-v', '--reruns=2', '--reruns-delay 2'])<br />
配置执行次数越多（如--reruns=2），执行的成功率越高。</p>
<p>命令行参数：<br />
--reruns n（重新运行次数），--reruns-delay m（等待运行秒数）</p>
<p>9.Mark装饰器之order执行顺序<br />
需要先安装插件</p>
<p>cmd命令窗口：pip install pytest-ordering<br />
在pycharm中File--&gt;settings--&gt;Project--&gt;Python Interpreter--&gt;点击+号--&gt;搜索pytest-ordering安装。</p>
<p>查看安装版本：pip show pytest-ordering</p>
<p>使用方法：</p>
<p>控制用例执行顺序的方法；<br />
在需要调整用例执行顺序的函数（或方法）前增加，如@pytest.mark.run(order=x)，x表示数字；<br />
执行顺序，由小到大、由正到负、未标记的在正数后、负数前执行，顺序为：1，2，3，无标记，-3，-2，-1；<br />
实例</p>
<p>import pytest</p>
<p>class Test_Class3():<br />
@pytest.mark.run(order=2)<br />
def test_case1(self):<br />
print(&quot;测试方法1&quot;)</p>
<pre><code>@pytest.mark.run(order=1)
def test_case2(self):
    print("测试方法2")

@pytest.mark.run(order=3)
def test_case3(self):
    print("测试方法3")</code></pre>
<p>if <strong>name</strong> == '<strong>main</strong>':<br />
pytest.main(['Test_demo02.py' '-s'])</p>
<p>10.setup、teardown<br />
setup_class()和 teardown_class()函数<br />
需要定义在测试类中，定义在类外不起作用。<br />
setup_class()定义场景，比如：创建日志对象，创建数据库的连接，创建接口的请求对象等。<br />
teardown_class()定义场景，比如：销毁日志对象，销毁数据库的连接，销毁接口的请求对象。<br />
&quot;&quot;&quot;<br />
函数需要定义在测试类中，定义在类外不起作用。<br />
setup_method()和 teardown_method(),在每个测试方法之前/之后执行。定义场景，比如：打开浏览器/关闭浏览器。<br />
setup_class()定义场景，比如：创建日志对象，创建数据库的连接，创建接口的请求对象等。<br />
teardown_class()定义场景，比如：销毁日志对象，销毁数据库的连接，销毁接口的请求对象。<br />
&quot;&quot;&quot;</p>
<p>import pytest</p>
<p>class Test_setUp_tearDown:</p>
<pre><code># 方法级，前置函数
def setup_method(self):
    # print("setup_method(self):在每个测试方法之前执行")
    print("在每个测试方法之前执行")

# 方法级，后置函数
def teardown_method(self):
    # print("teardown_method(self):在每个测试方法之后执行\n")
    print("在每个测试方法之后执行")

# 类级，前置函数
def setup_class(self):
    # print("setup_class(self)：每个测试类之前执行一次\n")
    print("每个测试类之前执行一次")

# 类级，后置函数
def teardown_class(self):
    # print("teardown_class(self)：每个测试类之后执行一次")
    print("每个测试类之后执行一次")

# 测试用例a
def test_a(self):
    print("test_a方法")
    assert True

# 测试用例b
def test_b(self):
    print("test_b方法")
    assert True</code></pre>
<p>if <strong>name</strong> == '<strong>main</strong>':<br />
pytest.main()<br />
pytest钩子函数</p>
<p>在pytest中，钩子函数是一种特殊的函数，用于在测试执行过程中的特定阶段插入自定义逻辑。pytest提供了许多内置的钩子函数，这些钩子函数允许您在测试的不同阶段进行自定义操作。以下是pytest中常用的钩子函数及其作用</p>
<p>1.作用在类以外的钩子函数<br />
1 setup()/tear_down()<br />
def setup(): print(&quot;这是一个setup&quot;)<br />
def teardown(): print(&quot;这是一个teardown&quot;)<br />
2 setup_module()/teardown_module()</p>
<pre><code>    setup_module()：在测试模块开始之前运行，用于设置模块级别的资源或配置。可以在该钩子函数中执行一次性的模块设置。

    teardown_module()：在测试模块结束之后运行，用于清理模块级别的资源或配置。可以在该钩子函数中执行一次性的模块清理。

    def setup_module(self):
        print("这个是模块级别的setup_module")

    def teardown_module(self):
        print("这个是模块级别的teardown_module")</code></pre>
<p>3 setup_function/teardown_function</p>
<p>每条用例执行前执行一次，不会作用于class中的test_case</p>
<pre><code>    setup_function()：在每个测试函数开始之前运行，用于设置单个测试函数的资源或配置。可以在该钩子函数中执行每个测试函数的准备工作。

    teardown_function()：在每个测试函数结束之后运行，用于清理单个测试函数的资源或配置。可以在该钩子函数中执行每个测试函数的清理工作。      

    def setup_function()

        print("setup_function模块中每条用例执行前执行一次！")
    def teardown_function():
        print("teardown_function 模块中每条用例执行后执行一次！") </code></pre>
<p>2.作用在类中的钩子函数<br />
setup_class()：在每个测试类开始之前运行，用于设置单个测试类的资源或配置。可以在该钩子函数中执行每个测试类的准备工作。</p>
<pre><code>    teardown_class()：在每个测试类结束之后运行，用于清理单个测试类的资源或配置。可以在该钩子函数中执行每个测试类的清理工作。

    setup_method()：在每个测试方法开始之前运行，用于设置单个测试方法的资源或配置。可以在该钩子函数中执行每个测试方法的准备工作。

    teardown_method()：在每个测试方法结束之后运行，用于清理单个测试方法的资源或配置。可以在该钩子函数中执行每个测试方法的清理工作。</code></pre>
<p>3.pytest_runtest_makereport 钩子函数<br />
pytest_runtest_makereport 是一个重要的钩子，它在测试运行期间被调用，用于生成测试报告。通过覆盖这个钩子，你可以自定义测试报告的行为，例如在测试失败时执行某些操作，或者收集额外的信息。</p>
<p>示例</p>
<p>import pytest</p>
<p>@pytest.hookimpl(tryfirst=True, hookwrapper=True)<br />
def pytest_runtest_makereport(item, call):</p>
<h1>execute all other hooks to get the report object</h1>
<p>outcome = yield<br />
rep = outcome.get_result()</p>
<pre><code># we only look at actual failing test calls, not setup/teardown
if rep.when == "call" and rep.failed:
    # 自定义逻辑：当测试失败时的操作
    print(f"Test {item.name} failed")
    # 你可以在这里添加更多的逻辑，例如记录日志、发送邮件等</code></pre>
<p>在这个示例中，我们使用 @pytest.hookimpl 装饰器定义了一个 pytest_runtest_makereport 钩子函数。参数 tryfirst=True 表示这个钩子应该尽可能早地被调用，而 hookwrapper=True 表示这是一个钩子包装器，它会先执行其他注册的钩子函数，然后执行自己的逻辑。</p>
<p>钩子详解</p>
<p>item：当前正在运行的测试项。<br />
call：当前测试阶段（setup、call 或 teardown）。<br />
rep：测试报告对象，包含测试的结果信息。<br />
示例中的逻辑</p>
<p>outcome = yield：这部分代码使用 yield 来执行其他注册的钩子函数，并获取它们的结果。这是 hookwrapper 的典型用法。<br />
rep = outcome.get_result()：获取测试报告对象。<br />
条件判断：if rep.when == &quot;call&quot; and rep.failed: 检查当前阶段是否为测试执行阶段（而非 setup 或 teardown），并且测试是否失败。<br />
自定义逻辑：在测试失败时执行自定义的逻辑，例如打印一条消息。<br />
完整的插件示例</p>
<p>如果你需要将这个钩子放入一个插件中，可以创建一个 .py 文件（例如 my_plugin.py），并在其中定义这个钩子：</p>
<p>import pytest</p>
<p>class MyPlugin:<br />
@pytest.hookimpl(tryfirst=True, hookwrapper=True)<br />
def pytest_runtest_makereport(self, item, call):</p>
<h1>execute all other hooks to get the report object</h1>
<p>outcome = yield<br />
rep = outcome.get_result()</p>
<pre><code>    # we only look at actual failing test calls, not setup/teardown
    if rep.when == "call" and rep.failed:
        # 自定义逻辑：当测试失败时的操作
        print(f"Test {item.name} failed")
        # 你可以在这里添加更多的逻辑，例如记录日志、发送邮件等</code></pre>
<p>def pytest_configure(config):<br />
config.pluginmanager.register(MyPlugin(), &quot;my_plugin&quot;)</p>
<p>def pytest_unconfigure(config):<br />
plugin = getattr(config, &quot;my_plugin&quot;, None)<br />
if plugin is not None:<br />
config.pluginmanager.unregister(plugin)<br />
在这个示例中，我们定义了一个 MyPlugin 类，并在其中实现了 pytest_runtest_makereport 钩子。我们还在 pytest_configure 和 pytest_unconfigure 函数中注册和注销插件。</p>
<p>通过这种方式，你可以轻松地扩展 pytest 的功能，自定义测试报告的行为。</p>
<p>4 pytest_sessionfinish(session, exitstatus) 钩子函数<br />
pytest_sessionfinish 是 pytest 提供的一个钩子（hook），它允许你在整个测试会话结束时执行一些操作。这个钩子在所有测试项运行完毕后被调用，但在此之前所有测试收集、设置（setup）、执行以及清理（teardown）都已经完成。这意味着你可以利用这个钩子来做一些总结性的工作，比如输出一些统计信息，关闭资源，清理环境等。</p>
<p>这个钩子有两个参数：</p>
<p>session: 一个 Session 对象，提供了对当前测试会话的信息访问。<br />
exitstatus: 一个整数，表示测试会话的退出状态码。这可以用来决定脚本的退出状态，例如是否成功执行。<br />
如何使用 pytest_sessionfinish</p>
<p>下面是一个简单的例子来展示如何使用 pytest_sessionfinish 钩子：</p>
<p>import pytest</p>
<p>def pytest_sessionfinish(session, exitstatus):</p>
<h1>在这里添加你的逻辑</h1>
<p>print(&quot;All tests have finished.&quot;)<br />
print(f&quot;Exit status: {exitstatus}&quot;)</p>
<h1>你也可以根据 exitstatus 决定做一些不同的事情</h1>
<p>if exitstatus == 0:<br />
print(&quot;All tests passed.&quot;)<br />
else:<br />
print(&quot;Some tests did not pass.&quot;)<br />
更复杂的用法</p>
<p>如果你想要创建一个插件，可以像这样定义 pytest_sessionfinish 钩子：</p>
<p>import pytest</p>
<p>class MyPlugin:<br />
def pytest_sessionfinish(self, session, exitstatus):<br />
print(&quot;All tests have finished.&quot;)<br />
print(f&quot;Exit status: {exitstatus}&quot;)</p>
<p>def pytest_configure(config):</p>
<h1>注册插件</h1>
<p>config.pluginmanager.register(MyPlugin(), &quot;my_plugin&quot;)</p>
<p>def pytest_unconfigure(config):</p>
<h1>清理插件</h1>
<p>plugin = getattr(config, &quot;my_plugin&quot;, None)<br />
if plugin is not None:<br />
del config.my_plugin<br />
config.pluginmanager.unregister(plugin)<br />
Session 对象</p>
<p>session 参数是一个 pytest.Session 实例，它提供了许多有用的方法和属性来访问关于测试会话的信息。例如，你可以使用 session.items 获取测试项列表，session.testsfailed 获取失败的测试数量，以及其他有用的统计信息。</p>
<p>Exit Status</p>
<p>exitstatus 是一个整数，表示测试会话的退出状态。常见的值包括：</p>
<p>0: 所有测试通过。<br />
1: 测试失败或命令行选项无效。<br />
2: 用户中断（Ctrl+C）。<br />
5: 内部错误。<br />
你可以根据这个状态码来决定后续的动作，例如发送通知或更新数据库的状态。</p>
<p>通过使用 pytest_sessionfinish 钩子，你可以确保在测试会话结束后执行一些必要的清理工作或通知操作。</p>
<p>pytest+allure测试报告(图文详解)<br />
0.入口python文件执行pytest程序，并生成报告展示<br />
os.system('python -m pytest --alluredir ./allure --clean-alluredir')<br />
time.sleep(3)<br />
os.system('allure serve ./allure')<br />
说明：</p>
<pre><code>    python -m pytest： -m使用pytest模块执行

   --alluredir ./allure：将测试结果保存到 allure目录中.(或者使用 --alluredir=./allure)，是pytest-allure-adaptor插件中的选项。

   --clean-alluredir：在保存测试结果之前先清理 allure 目录，是插件pytest-allure-adaptor 中的选项。</code></pre>
<p>————————————————</p>
<pre><code>                        版权声明：本文为博主原创文章，遵循 CC 4.0 BY-SA 版权协议，转载请附上原文出处链接和本声明。</code></pre>
<p>原文链接：<a href="https://blog.csdn.net/qadnkz/article/details/136333732">https://blog.csdn.net/qadnkz/article/details/136333732</a></p>]]></description>
    <pubDate>Tue, 17 Dec 2024 11:42:54 +0800</pubDate>
    <dc:creator>jm8X08LA</dc:creator>
    <guid>https://top.zhongtongzttb.com.cn/?post=24</guid>
</item>
<item>
    <title>接口自动化测试（Python+Requests+Unittest）</title>
    <link>https://top.zhongtongzttb.com.cn/?post=23</link>
    <description><![CDATA[<p><strong>缺点：</strong></p>
<ol>
<li>不能完全取代手工测试。（自动化永远不能替代手工测试，只是提高测试效率）</li>
<li>手工测试比自动化测试发现的缺陷更多，自动化测试不容易发现新的BUG。</li>
</ol>
<blockquote>
<p>GET请求和POST请求的区别：</p>
</blockquote>
<ol>
<li>GET请求一般是 <code>从后台服务器上获取数据用于前端页面的展示</code>（例如：看到列表页面等），POST请求是 <code>向服务器传送数据</code>（登录、注册、上传文件、发布文章）。什么时候用GET，什么时候用POST取决于开发。无论用POST请求还是GET请求，都能完成对数据的增删改查，分不同的请求方式更多的是一种约定。</li>
<li>GET请求的 <code>请求参数是拼接在url后面的，只能以文本的形式传递参数，请求参数会显示在地址栏，数据长度受限于url的长度，传递的数据量小（4KB左右，不同浏览器会有差异）</code>，POST请求的 <code>请求参数是放在request body里面，传递数据量大（默认8M），对数据长度也没有要求</code>。GET请求可以在浏览器中直接访问，而POST请求只能借助工具完成（比如：postman、jmeter）。</li>
<li>GET请求速度快，安全性不高；POST请求一般用于像登录这种安全性要求高的场合，请求不会被缓存，也不会保留在浏览器的历史记录中。</li>
<li>
</li>
</ol>
<p>前后端分离</p>
<p><strong>开发模式</strong></p>
<p>以前老的方式：</p>
<ul>
<li>产品经理 / 领导 / 客户提出需求（提出文字需求）</li>
<li>UI做出设计图</li>
<li>前端工程师做html页面（用户能看到的页面）</li>
<li>后端工程师将html页面套成jsp页面（前后端强依赖，后端必须要等到前端的html页面做好才能套jsp。如果html发生变更，就很麻烦，开发效率低）</li>
<li>集成出现问题</li>
<li>前端返工</li>
<li>后端返工</li>
<li>二次集成</li>
<li>集成成功</li>
<li>交付</li>
</ul>
<p>新的方式：</p>
<ul>
<li>产品经理 / 领导 / 客户提出需求（提出文字需求）</li>
<li>UI做出设计图</li>
<li>前后端约定接口 &amp; 数据 &amp; 参数</li>
<li>前后端并行开发（无强依赖，可前后端并行开发，如果需求变更，只要接口 &amp; 参数不变，就不用两边都修改代码，开发效率高）</li>
<li>前后端集成</li>
<li>前端页面调整</li>
<li>集成成功</li>
<li>交付</li>
</ul>
<p>🤑通过F12打开浏览器开发者工具进行抓包，返回数据是json格式的就是前后端分离，返回时html页面就是没有前后端分离。</p>
<blockquote>
<p>微服务的概念：</p>
</blockquote>
<p>将大模块切分成小模块。减少代码的耦合度，从而降低模块与模块之间的影响。原先是一个jar包里面包含所有模块，改一个模块就有可能影响其他模块，现在是将一个一个的模块都打成一个一个的jar包，模块与模块之间的交互通过接口，哪个模块出了问题，只需要修改那个模块的jar包，避免因为修改一个模块的代码导致其他模块出错。</p>
<h3>(2)Python requests框架讲解</h3>
<blockquote>
<p>接口自动化requests环境搭建</p>
</blockquote>
<p>接口自动化核心库：requests</p>
<p><strong>安装requests库的方法：</strong></p>
<p><strong><em>方法一：</em></strong></p>
<p>命令行安装，打开cmd或者终端，输入以下命令：</p>
<p><img src="https://top.zhongtongzttb.com.cn/content/uploadfile/202412/a2b41733123971.png" alt="image-20210107214728817" /></p>
<p><strong><em>方法二：</em></strong><br />
在pycharm中安装，settings --&gt; Project --&gt; Project Interpreter --&gt; 点击“+”号 --&gt; 输入request安装</p>
<p><img src="https://top.zhongtongzttb.com.cn/content/uploadfile/202412/64521733123971.png" alt="image-20210108203030662" /></p>
<blockquote>
<p><code>测试环境是否ok</code></p>
<p>import requests</p>
<p>url_toutiao = “<a href="https://www.ixigua.com/tlb/comment/article/v5/tab_comments/?tab_index=0&amp;count=10&amp;group_id=6914830518563373581&amp;item_id=6914830518563373581&amp;aid=1768">https://www.ixigua.com/tlb/comment/article/v5/tab_comments/?tab_index=0&amp;count=10&amp;group_id=6914830518563373581&amp;item_id=6914830518563373581&amp;aid=1768</a>”</p>
<p>方式一：<br />
result_toutiao = requests.get(url_toutiao)<br />
方式二：<br />
result_toutiao = requests.get(url=url_toutiao)</p>
<p>方式三：<br />
result_toutiao = requests.get(<br />
“<a href="https://www.ixigua.com/tlb/comment/article/v5/tab_comments/?tab_index=0&amp;count=1&amp;group_id=6914830518563373581&amp;item_id=6914830518563373581&amp;aid=1768">https://www.ixigua.com/tlb/comment/article/v5/tab_comments/?tab_index=0&amp;count=1&amp;group_id=6914830518563373581&amp;item_id=6914830518563373581&amp;aid=1768</a>”)<br />
print(result_toutiao.json())<br />
print(type(result_toutiao.json())) # &lt;class ‘dict’&gt;<br />
result = result_toutiao.json()<br />
print(result)<br />
expect_result = “华晨金杯汽车花朵朵”<br />
actual_result = result[“data”][0][“comment”][“user_name”]<br />
print(actual_result)<br />
if expect_result == actual_result:<br />
print(“pass!”)<br />
else:<br />
print(“failed!”)</p>
</blockquote>]]></description>
    <pubDate>Mon, 02 Dec 2024 15:00:42 +0800</pubDate>
    <dc:creator>jm8X08LA</dc:creator>
    <guid>https://top.zhongtongzttb.com.cn/?post=23</guid>
</item>
<item>
    <title>Python 接口自动化测试：10个实战案例</title>
    <link>https://top.zhongtongzttb.com.cn/?post=22</link>
    <description><![CDATA[<ol>
<li>
<p>1、数据验证接口<br />
class DataValidator:<br />
@staticmethod<br />
def validate_email(email):# 使用正则表达式验证邮箱格式</p>
<p>import re<br />
pattern = r'\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+.[A-Z|a-z]{2,}\b'<br />
return bool(re.match(pattern, email))</p>
</li>
<li>
<p>2、HTTP 请求封装<br />
import requests<br />
class HTTPClient:<br />
@staticmethod<br />
def get(url, params=None):<br />
response = requests.get(url, params=params)<br />
return response.json()</p>
</li>
<li>
</li>
<li>
</li>
<li>
</li>
<li>
<p>3、文件读写接口<br />
class FileHandler:<br />
@staticmethod<br />
def write_to_file(filename, content):<br />
with open(filename, 'w') as file:<br />
file.write(content)<br />
@staticmethod<br />
def read_from_file(filename):<br />
with open(filename, 'r') as file:<br />
return file.read()</p>
</li>
<li>
</li>
<li>
</li>
<li>
<p>4、数据解析器</p>
</li>
<li>
<p>import json<br />
class JSONParser:<br />
@staticmethod<br />
def parse(json_string):<br />
return json.loads(json_string)<br />
@staticmethod<br />
def stringify(data):<br />
return json.dumps(data)</p>
</li>
<li>
</li>
<li>
</li>
<li>
<p>5、时间日期处理接口<br />
from datetime import datetime<br />
class DateTimeUtils:<br />
@staticmethod<br />
def format_datetime(dt=datetime.now()):<br />
return dt.strftime('%Y-%m-%d %H:%M:%S')</p>
</li>
<li>
</li>
<li>
<p>6、数据加密解密</p>
</li>
<li>
<p>from cryptography.fernet import Fernet<br />
class Crypto:<br />
def <strong>init</strong>(self, key):<br />
self.key = key<br />
self.cipher_suite = Fernet(key)<br />
def encrypt(self, data):<br />
return self.cipher_suite.encrypt(data.encode())<br />
def decrypt(self, token):<br />
return self.cipher_suite.decrypt(token).decode()</p>
</li>
<li>
</li>
<li>
<p>7、数据持久化接口（使用SQLite）<br />
import sqlite3<br />
class Database:<br />
def <strong>init</strong>(self, db_name='data.db'):<br />
self.conn = sqlite3.connect(db_name)<br />
self.cursor = self.conn.cursor()<br />
def execute(self, query, data=None):<br />
if data:<br />
self.cursor.execute(query, data)<br />
else:<br />
self.cursor.execute(query)<br />
self.conn.commit()<br />
def fetch_all(self, query):<br />
self.cursor.execute(query)<br />
return self.cursor.fetchall()</p>
</li>
<li>
<p>8、图像处理接口<br />
from PIL import Image<br />
class ImageProcessor:<br />
@staticmethod<br />
def resize_image(image_path, size=(100, 100)):<br />
img = Image.open(image_path)<br />
img_resized = img.resize(size)<br />
img<em>resized.save('resized</em>' + image_path)</p>
</li>
<li>
<p>9、异常处理接口<br />
class ErrorHandler:<br />
@staticmethod<br />
def handle_exception(func):<br />
def wrapper(*args, *<em>kwargs):<br />
try:<br />
return func(</em>args, **kwargs)<br />
except Exception as e:<br />
print(f&quot;Error occurred: {e}&quot;)<br />
return wrapper</p>
</li>
<li>
<p>10、配置加载接口<br />
import yaml<br />
class ConfigLoader:<br />
@staticmethod<br />
def load_config(config_file='config.yaml'):<br />
with open(config_file, 'r') as file:<br />
return yaml.safe_load(file)</p>
</li>
</ol>]]></description>
    <pubDate>Fri, 29 Nov 2024 14:24:22 +0800</pubDate>
    <dc:creator>jm8X08LA</dc:creator>
    <guid>https://top.zhongtongzttb.com.cn/?post=22</guid>
</item>
<item>
    <title>超详细python接口自动化测试requests实战教学</title>
    <link>https://top.zhongtongzttb.com.cn/?post=21</link>
    <description><![CDATA[<p>一、前言<br />
Requests是用python语言基于urllib编写的，采用的是Apache2Licensed开源协议的HTTP库，Requests它会比urllib更加方便，可以节约我们大量的工作</p>
<p>本质就是模拟get与post请求 安装 dos命令窗口</p>
<p>pip  install requests</p>
<p>要是下载慢的话 在 pip install 包名 后面加上 -i + 镜像地址，这样 pip 安装时即可成倍的提速了 pip 安装时提速的格式如下：</p>
<p>pip install 包名 -i <a href="https://pypi.tuna.tsinghua.edu.cn/simple">https://pypi.tuna.tsinghua.edu.cn/simple</a></p>
<p>国内主要镜像地址如下：</p>
<h1>清华：</h1>
<p><a href="https://pypi.tuna.tsinghua.edu.cn/simple">https://pypi.tuna.tsinghua.edu.cn/simple</a></p>
<h1>阿里云：</h1>
<p><a href="http://mirrors.aliyun.com/pypi/simple/">http://mirrors.aliyun.com/pypi/simple/</a></p>
<h1>中国科技大学:</h1>
<p><a href="https://pypi.mirrors.ustc.edu.cn/simple/">https://pypi.mirrors.ustc.edu.cn/simple/</a></p>
<h1>华中理工大学：</h1>
<p><a href="http://pypi.hustunique.com/">http://pypi.hustunique.com/</a></p>
<h1>山东理工大学：</h1>
<p><a href="http://pypi.sdutlinux.org/">http://pypi.sdutlinux.org/</a></p>
<h1>豆瓣：</h1>
<p><a href="http://pypi.douban.com/simple/">http://pypi.douban.com/simple/</a></p>
<p>二、模拟get请求</p>
<h1>模拟get请求</h1>
<h1>第一步导入requests模块</h1>
<h1>第二步模拟get请求</h1>
<p>import requests</p>
<h1>get()放法就是用来模拟get请求    url就是请求地址</h1>
<h1>reponse获取响应对象   对象名称  包含所有的响应信息</h1>
<p>reponse= requests.get(url=&quot;<a href="http://192.168.0.17/phpwind">http://192.168.0.17/phpwind</a>&quot; )</p>
<p>print(reponse.status_code)    #响应状态码获取<br />
print(reponse.reason)       #响应信息获取<br />
print(reponse.headers)      #响应头部信息获取<br />
print(reponse.text)       #响应正文获取</p>
<p>三、模拟带参数的get请求</p>
<h1>模拟带参数的get请求</h1>
<p>import requests</p>
<h1>方式一：把url参数写在请求地址后面</h1>
<h1>reponse=requests.get(url='<a href="http://192.168.0.17/phpwind/read.php?tid=2&amp;fid=2">http://192.168.0.17/phpwind/read.php?tid=2&amp;fid=2</a>')</h1>
<h1>print(reponse.text)</h1>
<h1>方式二：把url参数做成字典，然后在get()方法中  使用参数params传入字典</h1>
<p>url_params={<br />
&quot;tid&quot;:2,<br />
&quot;fid&quot;:2</p>
<p>}<br />
reponse=requests.get(url='<a href="http://192.168.0.17/phpwind/read.php">http://192.168.0.17/phpwind/read.php</a>',<br />
params=url_params)<br />
print(reponse.text)</p>
<p>四、解析json数据</p>
<h1>pyhton处理json数据</h1>
<h1>在python中  字典类型的数据就是json的键值对形式    列表类型就是json数组形式</h1>
<h1>json数据  必须使用双引号&quot;&quot;</h1>
<p>import  json</p>
<h1>字符串和json数据的相互转换</h1>
<p>str_01='{&quot;name&quot;:&quot;张三&quot;,&quot;age&quot;:20}'</p>
<h1>str_01=&quot;&quot;   #json数据必须使用双引号  否则会报错</h1>
<p>json_obj_01=json.loads(str_01)    #loads  把字符串转换成json数据  前提字符串必须是json数据<br />
print(json_obj_01)<br />
print(type(json_obj_01))</p>
<p>json_obj_02 = {&quot;name&quot;:&quot;张三&quot;,&quot;age&quot;:20}</p>
<h1>会自动把中文转换成unicode编码</h1>
<p>str_02 = json.dumps(json_obj_02,ensure_ascii=False)   #使用ensure_ascii会关闭自动转换<br />
print(str_02)<br />
print(type(str_02))</p>
<h1>json数据解析</h1>
<p>import jsonpath      #jsonpath通用的json数据解析模块  java  python 都有这个包<br />
json_obj_03={&quot;name&quot;:&quot;张三&quot;,&quot;age&quot;:20}<br />
value=jsonpath.jsonpath(json_obj_03,'$.name')[1]<br />
print(value)</p>
<p>五、模拟post请求</p>
<h1>模拟post请求编辑标签</h1>
<p>import requests,j son,jsonpath</p>
<p>url<em> aprams={&quot;access</em> token&quot;:&quot;57135BrbDZbsPz0iM9LP4icmRRMuRubgXA- rBbKXkvE5HT4fqRT}</p>
<p>post_ data = {&quot;tag&quot; : {&quot;id&quot;:103，&quot;name&quot; :“北京老帽”}}</p>
<h1>先将json数据转换成字符串</h1>
<p>post_ str = json.dumps(post<em>data,ensure</em> ascii=False)</p>
<p>response = requests.post(url =&quot;https:/ /api.weixin.qq.com/cgi-bin/tags/update&quot;,Darams= urL_ aprams,</p>
<h1>json=post_ data #json必须传 json数据</h1>
<h1>利用data传入字符串数据 用encode('utf-8.)解决乱码格式</h1>
<p>data=post_ str .encode('utf-8'))<br />
print (response. text)</p>
<p>六、获取响应正文text/content/json()/raw</p>
<h1>获取响应信息</h1>
<h1>响应行  响应头  响应正文</h1>
<p>import requests<br />
response=requests.get(url=&quot;<a href="http://www.baidu.com">http://www.baidu.com</a>&quot;)<br />
print(response.url)   #获取url<br />
print(response.headers)     #.get()  []去获取单独的头<br />
print(response.encoding)   #获取网页编码格式1</p>
<h1>requests根据 响应信息头中的 charset  字段判断网页编码格式  如果没有该字段  则默认为ISO-8859-1  具体表现为乱码</h1>
<p>print(response.apparent_encoding)   #获取网页编码格式2</p>
<h1>requests根据 响应正文中的 charset 进行获取网页编码格式</h1>
<p>response.encoding=response.apparent_encoding</p>
<h1>把响应正文的编码类型设置为由响应正文的charset字段获取</h1>
<h1>print(response.text)   #以字符串文本的方式获取响应正文</h1>
<h1>以二进制的方式获取响应正文 (普通网页、下载文件、图片、视频等二进制文件   )</h1>
<p>print(response.content.decode('utf-8'))</p>
<h1>响应正文为二进制数据</h1>
<p>import requests<br />
from PIL import Image       #pil操作图片<br />
from io import BytesIO      #字节流</p>
<p>response=requests.get(url=&quot;<a href="https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fimg.mp.itc.cn%2Fupload%2F20170719%2F2f4b26eebc3c4c63b25b7e98d65a0cb1_th.jpg&amp;refer=http%3A%2F%2Fimg.mp.itc.cn&amp;app=2002&amp;size=f9999,10000&amp;q=a80&amp;n=0&amp;g=0n&amp;fmt=auto?sec=1655610368&amp;t=75ee6522d3101672a7ae0667b676c6e6">https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fimg.mp.itc.cn%2Fupload%2F20170719%2F2f4b26eebc3c4c63b25b7e98d65a0cb1_th.jpg&amp;refer=http%3A%2F%2Fimg.mp.itc.cn&amp;app=2002&amp;size=f9999,10000&amp;q=a80&amp;n=0&amp;g=0n&amp;fmt=auto?sec=1655610368&amp;t=75ee6522d3101672a7ae0667b676c6e6</a>&quot;)<br />
img_bytes=BytesIO(response.content)    #把获取的二进制图片对象转换成字节流<br />
img_ogj=Image.open(img_bytes)  #创建图像对象  打开字节流图片<br />
img_ogj.save('test.png')  #保存图片</p>
<h1>响应正文为json数据</h1>
<p>import requests,jsonpath<br />
url_params={<br />
&quot;grant_type&quot;:&quot;client_credential&quot;,<br />
&quot;appid&quot;:&quot;wxb61e6693c7244793&quot;,<br />
&quot;secret&quot;:&quot;c146872139641af2be50a94a01aee9a7&quot;<br />
}</p>
<p>response=requests.get(url=&quot;<a href="https://api.weixin.qq.com/cgi-bin/token">https://api.weixin.qq.com/cgi-bin/token</a>&quot;<br />
,params=url_params)</p>
<h1>如果已知道返回的数据格式是json格式的正文    可以直接返回json对象</h1>
<p>json_body=response.json()<br />
token_value=jsonpath.jsonpath(json_body,&quot;$.access_token&quot;)[0]<br />
print(token_value)</p>
<h1>响应正文返回原始数据  raw    几乎不用</h1>
<p>import requests</p>
<p>response=requests.get(url=&quot;<a href="https://www.baidu.com&quot;,stream=True">https://www.baidu.com",stream=True</a>)<br />
print(response.raw.read(10))   #返回原始套接字内容</p>
<p>七、pil 操作图片<br />
import requests<br />
from PIL import Image       #pil操作图片<br />
from io import BytesIO      #字节流</p>
<p>response=requests.get(url=&quot;<a href="https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fimg.mp.itc.cn%2Fupload%2F20170719%2F2f4b26eebc3c4c63b25b7e98d65a0cb1_th.jpg&amp;refer=http%3A%2F%2Fimg.mp.itc.cn&amp;app=2002&amp;size=f9999,10000&amp;q=a80&amp;n=0&amp;g=0n&amp;fmt=auto?sec=1655610368&amp;t=75ee6522d3101672a7ae0667b676c6e6">https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fimg.mp.itc.cn%2Fupload%2F20170719%2F2f4b26eebc3c4c63b25b7e98d65a0cb1_th.jpg&amp;refer=http%3A%2F%2Fimg.mp.itc.cn&amp;app=2002&amp;size=f9999,10000&amp;q=a80&amp;n=0&amp;g=0n&amp;fmt=auto?sec=1655610368&amp;t=75ee6522d3101672a7ae0667b676c6e6</a>&quot;)<br />
img_bytes=BytesIO(response.content)    #把获取的二进制图片对象转换成字节流<br />
img_ogj=Image.open(img_bytes)  #创建图像对象  打开字节流图片<br />
img_ogj.save('test.png')  #保存图片</p>
<p>八、代理设置</p>
<h1>requests  设置代理    必须有代理服务器打开</h1>
<p>import requests</p>
<p>proxy_server={<br />
&quot;http&quot;:&quot;<a href="http://127.0.0.1:8888">http://127.0.0.1:8888</a>&quot;,<br />
&quot;https&quot;:&quot;<a href="https://127.0.0.1:8888">https://127.0.0.1:8888</a>&quot;<br />
}</p>
<p>response=requests.get(url=&quot;<a href="http://192.168.0.17/phpwind">http://192.168.0.17/phpwind</a>&quot;,<br />
proxies=proxy_server)</p>
<h1>带密码的代理   <a href="http://用户名:密码@127.0.0.1:8888">http://用户名:密码@127.0.0.1:8888</a></h1>
<p>九、超时处理</p>
<h1>超时设置</h1>
<p>import requests</p>
<p>reponse = requests.get(url=&quot;<a href="http://192.168.0.17/phpwind">http://192.168.0.17/phpwind</a>&quot;,</p>
<h1>timeout=0.001)#timeout  设置的是float  响应时间是响应超时设置</h1>
<p>timeout=(0.05, 0.04))  # timeout  设置的是tuple</p>
<h1>0.05是链接服务器超时时间   0.04表示响应超时时间设置</h1>
<p>print(reponse.text)</p>
<p>十、重定向</p>
<h1>requests  是默认支持重定向操作</h1>
<p>import requests</p>
<h1>allow_redirects   默认设置为true  支持重定向   true打开  false关闭</h1>
<p>response=requests.get(url=&quot;<a href="http://www.360buy.com&quot;,allow_redirects=False">http://www.360buy.com",allow_redirects=False</a>)<br />
print(response.history)    #查看重定向过程<br />
print(response.content.decode('utf-8'))</p>
<p>requests在模拟https请求时</p>
<p>如果要模拟的系统需要进行证书认证（极少网站）才能访问</p>
<p>那么此时汇报如下错误 SSL error</p>
<p>处理方式： 处理方式一：使用verifyFalse 忽略证书认证过程</p>
<p>新版本的urllib3 不支持 要使用方式一 需要降级urllib3</p>
<p>pip install urllib3==1.25.7<br />
1<br />
处理方式二：使用cert=证书路径 来解决</p>
<p>十一、自带的异常处理</p>
<h1>requests自带的异常处理</h1>
<h1>Exception  是所有异常类的父类</h1>
<h1>RequestException   是requests  包 异常类的父类</h1>
<p>import requests</p>
<p>from requests.exceptions import InvalidURL<br />
from requests.exceptions import RequestException<br />
try:<br />
response = requests.get(url=&quot;https: //www.baidu.com&quot;)<br />
except InvalidURL as e:      #子--子<br />
print('无效的url连接')<br />
except RequestException as e:   #子<br />
print('请求异常，具体原因未知')<br />
except Exception as e:    #父<br />
print('系统异常，具体原因未知')</p>
<h1>print(response.text)</h1>
<p>最后： 可以在公众号：伤心的辣条 ！ 自行领取一份216页软件测试工程师面试宝典文档资料【免费的】。以及相对应的视频学习教程免费分享！，其中包括了有基础知识、Linux必备、Shell、互联网程序原理、Mysql数据库、抓包工具专题、接口测试工具、测试进阶-Python编程、Web自动化测试、APP自动化测试、接口自动化测试、测试高级持续集成、测试架构开发测试框架、性能测试、安全测试等。</p>]]></description>
    <pubDate>Thu, 28 Nov 2024 15:11:47 +0800</pubDate>
    <dc:creator>jm8X08LA</dc:creator>
    <guid>https://top.zhongtongzttb.com.cn/?post=21</guid>
</item>
<item>
    <title>Python自动化测试五大框架</title>
    <link>https://top.zhongtongzttb.com.cn/?post=19</link>
    <description><![CDATA[<p>1.Robot Framework<br />
作为最重要的Python测试框架之一，RobotFramework主要被用在测试驱动(test-driven)类型的开发与验收中。虽然是由Python开发而来，但是它也可以在基于.Net的IronPython和基于Java的Jython上运行。同时，作为一个Python框架，Robot还能够兼容诸如Windows、MacOS、以及Linux等平台。</p>
<p>使用先决条件<br />
在使用Robot Framework(RF)之前，您需要先安装Python 2.7.14及以上的版本。我推荐您使用Python 3.6.4，以确保适当的注释能够被添加到代码段中，并能够跟踪程序的更改。同时，您还需要安装Python包管理器–pip。</p>
<p>当然，您也必须下载相应的开发框架，例如：在开发者圈子里比较流行的PyCharm社区版。另外，由于其代码段本身并不依赖于任何IDE，因此您完全可以沿用手头既有的IDE工具。</p>
<p>优点<br />
通过使用关键字驱动测试(keyword-driven-test)的方法，它能够帮助测试人员轻松地创建具有可读性的测试用例，进而简化了整个自动化的过程。<br />
用户能够轻松地测试数据中的语法。<br />
因为是由各种通用工具和测试库所组成，所以它不但拥有庞大的生态系统，而且可以在单独的项目中使用其各个元素。<br />
由于拥有许多类型的API，因此该框架具有高度的可扩展性。<br />
虽然并非内置功能，但是Robot可以通过Selenium Grid来帮助用户运行各种并行测试<br />
缺点<br />
虽然有着上述各种便利，但是Robot Framework在创建自定义的HTML报告方面比较繁琐。您顶多能用它来生成xUnit格式的简短报告。</p>
<p>另外，Robot Framework在并行测试方面也并不见长。</p>
<p>Robot的特点与竞品比较<br />
由于Robot具有丰富的内置库，并能使用更为简单的面向测试的DSL(Domain Specific Language)，因此如果您是自动化测试领域的新手，并且缺乏开发经验的话，那么将它作为Python测试框架要比下面将要提到的Pytest或Pyunit，更容易上手一些。当然，如果您需要开发复杂的自动化框架，那么还请使用Pytest、或其他类型的Python框架。</p>
<p>2.Pytest<br />
适用于多种软件测试的Pytest，是另一个Python类型的自动化测试框架。凭借着其开源和易学的特点，该工具经常被QA(质量分析)团队、开发团队、个人团队、以及各种开源项目所使用。鉴于Pytest具有“断言重写(assertrewriting)”之类的实用功能，许多大型互联网应用，如Dropbox和Mozilla，都已经从下面将要提到的unittest(Pyunit)切换到了Pytest之上。</p>
<p>使用先决条件<br />
除了基本的Python知识，用户并不需要更多的技术储备。另外，用户只需要有一台带有命令行界面的测试设备，并且安装好了Python包管理器、以及可用于开发的IDE工具。</p>
<p>优点<br />
过去，开发人员必须将他们的测试包含在各种大型的类中。如今，Pytest可以让用户写出更为紧凑的测试套件。<br />
其他的测试工具会要求开发或测试人员使用调试器，或以日志检查的方式检测某个特定值的来源。而用户在用Pytest来编写测试用例时，完全可以将所有的值都存储在测试用例之中，直到再获悉有哪些值失败了、以及哪些值得到了断言。<br />
由于涉及到的样板代码(boilerplate code)并不多，因此用户能够容易地编写和理解各种测试。<br />
测试夹具(Fixture)函数常被用来向测试函数添加某个参数，并返回不同的值。在Pytest中，您可以通过使用一个夹具来模块化另外一个。同时，用户可以使用多个夹具，在无需重写测试用例的情况下，将测试覆盖到所有参数的组合。<br />
Pytest开发人员通过发布各种实用插件，来保持框架的可扩展性。例如：pytest-xdist可以在不使用其他测试器的情况下，被用于执行并行测试。同时，单元测试也可以在无需复制任何代码的情况下，实现参数化。<br />
通过为开发人员提供各种特殊的例程，它能够使得测试用例的编写更为简单、更不易出错，同时代码也会变得更短、更易被理解。<br />
缺点<br />
上述提及的特殊例程，也意味着用户必须放弃一定的兼容性。虽然方便了用户编写测试用例，但是这些用例却无法与任何其他的测试框架一起被使用。</p>
<p>Pytest的特点与竞品比较<br />
就编写功能性测试用例和开发复杂的框架而言，Pytest胜过下面将要提到的UnitTest。不过，它和Robot Framework类似，仅适用于开发出简单的测试框架。</p>
<p>3.UnitTest/PyUnit<br />
受到了JUnit启发的UnitTest/PyUnit，也是一种标准化的针对单元测试的Python类自动化测试框架。它的基类TestCase提供了各种断言方法、以及所有清理和设置的例程。因此，TestCase子类中的每一种方法都是以“test”作为名词前缀，以标识它们能够被作为测试用例所运行。用户可以使用load方法和TestSuite类来分组、并加载各种测试。</p>
<p>当然，您也可以通过联合使用，来构建自定义的测试运行器。正如我们使用Junit去测试Selenium那样，UnitTest也会用到UnitTest-sml-reporting、并能生成各种XML类型的报告。</p>
<p>使用先决条件<br />
由于UnitTest默认使用了Python，因此我们并不需要什么先决条件。除了需要具备Python框架的基本知识，您也可以额外地安装pip、以及用于开发的IDE工具。</p>
<p>优点<br />
开发人员并不需要安装任何其他的模块。<br />
UnitTest是xUnit的衍生产品，其工作原理与其他xUnit框架十分类似。因此对于那些没有过硬Python背景的人来说，也能很快地上手。<br />
用户能够以更为简单的方式运行单个测试用例。您只需在终端上预定好名称，该框架便可灵活地执行各种用例的测试，并产生精炼的输出。<br />
它能够在几毫秒内生成各种测试报告。<br />
缺点<br />
虽然该框架常用snake_case来命名各种Python代码，但是由于它源自Junit，因此仍保留了一些传统的camelCase命名方法。这往往会让人产生混淆。</p>
<p>由于它过多地支持了抽象方法，因此造成了测试代码的目的有时不够清晰。需要大量的样板代码。</p>
<p>PyUnit的特点与竞品比较<br />
和部分Python开发人员的观点相似，我认为：Pytest能够培养测试人员以非常紧凑的方式编写出更好的自动化代码，这一编程习惯。尽管UnitTest是Python默认的自动化测试框架，但是其工作原理、及命名规则仍与标准的Python代码略有不同。同时，它也需要太多的样板代码。因此该框架并不太受欢迎。</p>
<p>4.Behave<br />
我们都知道：行为驱动开发(behavior-driven<br />
development，BDD)，是一种基于敏捷软件开发的方法。它能够鼓励开发人员、业务参与者和QA人员，三者之间的协作。作为另一种Python测试框架，Behave允许团队避开各种复杂的情况，去执行BDD测试。从本质上说，该框架与SpecFlow和Cucumber非常相似，常被用于执行自动化测试。用户可以通过简单易读的语言来编写测试用例，并能够在其执行期间粘贴到代码之中。而且，那些被设定的行为规范与步骤，也可以被重用到其他的测试方案中。</p>
<p>使用先决条件<br />
任何具备Python基础知识的人都可以使用Behave。其他先决条件还包括：</p>
<p>您必须先安装Python 2.7.14及以上的版本。</p>
<p>需要通过Python包管理器或pip来与Behave协作。</p>
<p>大多数开发人员会选择Pycharm作为开发环境，当然您也可以选用其他的IDE工具。</p>
<p>优点<br />
由于系统行为使用了半正式(semi-formal)语言、以及域词汇表(domain<br />
vocabulary)，因此Behave有助于在组织中保持一致性的行为。<br />
让那些工作在不同模块上的开发团队，通过协调处理来具有类似的特征。<br />
其构建的各个功能块能够执行各种测试用例。<br />
由于具有更多值得用户推理和思考的细节，因此目标产品会具有更好的规范性。<br />
根据类似的规范格式，它能够让项目经理和利益相关者，对开发团队和QA团队的输出具有更清楚地了解。<br />
缺点<br />
只适用于黑盒测试。</p>
<p>Behave的特点与竞品比较<br />
Behave最适合于诸如简单Web测试之类的黑盒测试。但是，对于那些具有复杂场景的集成测试与单元测试而言，Behave并不是一个很好的选择。作为Behave的替代品，一些开发与测试人员会推荐使用pytest-bdd。该工具融合了Pytest的所有优点，并实现了各种行为驱动测试的场景。</p>
<p>5.Lettuce<br />
Lettuce是另一种基于Cucumber和Python的行为驱动类自动化工具。Lettuce主要专注于那些具有行为驱动开发特征的普通任务。它不但简单易用，而且能够使得整个测试过程更流畅、甚至更有趣。</p>
<p>使用先决条件<br />
您需要安装带有IDE的Python 2.7.14、及以上的版本。当然，您也可以使用Pycharm或任何其他IDE工具。同时，您还需要安装Python包管理器。</p>
<p>优点<br />
和其他BDD测试框架类似，Lettuce能够让开发人员创建多个场景，并用简单的自然语言去描述不同的功能。<br />
根据类似的规范格式，开发与QA团队能够协调共事。<br />
对于黑盒测试而言，Lettuce非常适合于那些行为驱动的测试用例<br />
缺点<br />
为了成功地实现行为驱动测试，开发团队、QA人员以及利益相关者之间需要持续进行沟通。倘若缺乏此类沟通，则会产生流程模糊不清，并让团队遇到问题。竞品比较</p>
<p>在普通开发人员和自动化测试人员看来，Cucumber在执行BDD测试方面更为实用。而在Python开发和QA人员看来，Pytest-bdd才是的。Pytest的强大之处在于：其框架实现了紧凑且易于理解的代码，并能紧密地结合到行为驱动的测试之中。</p>]]></description>
    <pubDate>Thu, 28 Nov 2024 13:45:38 +0800</pubDate>
    <dc:creator>jm8X08LA</dc:creator>
    <guid>https://top.zhongtongzttb.com.cn/?post=19</guid>
</item>
<item>
    <title>Python自动化测试工具有哪些？哪一个更适合你呢？</title>
    <link>https://top.zhongtongzttb.com.cn/?post=18</link>
    <description><![CDATA[<p>前言<br />
Python自动化测试工具有哪些？</p>
<p>，我们先说说框架吧，常用的Python自动化测试框架有Robot Framework、Pytest、UnitTest/PyUnit、Behave、Lettuce。软件测试的自动化在预设条件下运行系统或应用程序，评估运行结果，预先条件应包括正常条件和异常条件。自动化测试以人为驱动的测试行为转化为机器执行的一种过程。</p>
<p>实现软件测试自动化得用到一些Python自动化测试框架和工具，让我们看看都有哪些？</p>
<p>Web UI test automation Web UI 自动化<br />
libraries 各种库</p>
<p>selenium webdriver - 浏览器自动化工具<br />
splinter - 简单的web自动化工具，让元素定位，表单提交等更加容易<br />
mechanize - 有状态可编程的浏览器<br />
frameworks and wrappers 框架和封装<br />
py.saunter - 有主见的自动化测试框架，使用了selenium RC和webdriver api<br />
moz-web-qa - py.test的插件，为Mozilla的WebQA项目提供了额外功能<br />
testutils sst - A web test framework that uses Python to generate functional browser-based tests.<br />
wtframework - 让web测试可以配置的框架<br />
holmium.core - Page Object及其他工具库支持<br />
robotframework-selenium2library - Robot Framework的selenium扩展<br />
gocept.selenium - selenium RC的API, 适合编写基于WSGI, Plone, Zope 2, ZTK, or Grok 应用的测试用例<br />
webium - 基于python的一个Page Object实现<br />
robotframework-anywherelibrary - Robot Framework的扩展库，使用selenium2测试web应用，使用appium测试移动应用<br />
robotframework-pageobjects - 一个不错的Page Object实现，可以脱离robot framework单独使用。 具体看这里<br />
elementium - 用jQuery风格的语法糖来实现浏览器的自动化测试用例<br />
slickqa - slick-webdriver-python 项目是python selenium binding的一个封装<br />
selene - Concise UI 测试用例，使用python实现支持Ajax,PageObjects和Widgets<br />
hitch - 编写基于service的应用的测试用例<br />
Needle - Needle是基于图片比对的测试工作，它可以对web应用的一部分进行截图，然后跟预期结果的图片进行比对<br />
PyPOM - PyPOM是另一个Page Object库，适用于Selenium和Splinter测试<br />
POM - POM是Page-Object-Model 微框架，目的是让Web UI测试更加简单，快速和有乐趣<br />
websmith - Web测试的一套DSL<br />
pages - 轻量的page object库和组建<br />
widgetastic - RedHat UI widget 组建框架<br />
navmazing - PageObjects based navigation from RedHat<br />
nightwatch - 基于python和selenium的UI 自动化测试框架. 灵感来源于nightwatch.js<br />
extensions 扩展：<br />
webdriver_manager - 主要目的是让不同版本的浏览器driver管理起来更加方便</p>
<p>pytest_splinter - pytest spinter 和 selenium的集成</p>
<p>lettuce_webdriver - Selenium webdriver 的 lettuce封装</p>
<p>Browsermob Proxy - python的Browsermob Proxy封装</p>
<p>FireRobot - 一个Firefox的扩展,让你可以更高效的编写基于robot framework的selenium用例</p>
<p>pytractor - Python的selenium扩展，以便更好的测试angular.js应用</p>
<p>Selenium-Requests - 扩展 Selenium WebDriver类，包含了Requests库的一些功能，可以更方便的处理cookie和请求头</p>
<p>selenium-respectful - selenium的封装，可以并行访问站点</p>
<p>Mobile test automation 移动端自动化测试工具<br />
appium - 开源的自动化测试框架，可以测试native/hybrid/mobile web应用。核心是基于webdriver协议进行了扩展<br />
Winium.StoreApps - 开源的自动化测试用具，用来测试Windows Store应用，实现了Selenium Remote WebDriver<br />
robotframework-androidlibrary - Robot Framework用来测试android应用的扩展库<br />
robotframework-appiumlibrary - appium的RobotFramework扩展<br />
robotframework-ioslibrary -Robot的ios测试扩展库<br />
uiautomator - Android uiautomator的python封装, 支持 Android 4.1+<br />
ATX - 智能机自动化测试工具. 支持 iOS, Android, WebApp 和游戏<br />
Windows UI test automation Windows的UI测试工具<br />
Winium.Desktop - 测试Windows应用(主要是基于WinForms和WPF平台)的自动化测试工具实现了Selenium Remote WebDriver协议<br />
PyAutoGUI - 跨平台的GUI测试工具，支持通过python脚本控制键盘和鼠标<br />
robotframework-autoitlibrary - Robot Framework的windows GUI测试扩展<br />
autopy - 简单跨平台的GUI测试工具集<br />
UISoup - 支持windows和MacOS平台的UI自动化(仅工作在x86平台)<br />
pywinauto - 非常有python面向对象风格的GUI测试库，现已支持64位机器以及py2和py3<br />
SikuliX - 基于OpenCV的 GUI 测试框架, 使用图片识别技术，支持python2.7<br />
Unix \ Linux UI test automation<br />
ldtp - 跨平台的linux GUI测试项目<br />
fMBT - 支持多平台的python GUI测试库<br />
SikuliX - 基于OpenCV的 GUI 测试框架, 使用图片识别技术，支持python2.7<br />
MacOS UI test automation MacOS UI自动化测试工具<br />
ATOMac - 通过Apple Accessibility API来测试Mac应用的python库<br />
PyAutoGUI - 跨平台的GUI测试工具，支持通过python脚本控制键盘和鼠标<br />
SikuliX - 基于OpenCV的 GUI 测试框架, 使用图片识别技术，支持python2.7<br />
PS:这些都各有各的特点，自动化测试工具个人还是较喜欢这两个：</p>
<p>windows上网页用Selenium<br />
移动app上用AirtestIDE</p>]]></description>
    <pubDate>Thu, 28 Nov 2024 13:41:02 +0800</pubDate>
    <dc:creator>jm8X08LA</dc:creator>
    <guid>https://top.zhongtongzttb.com.cn/?post=18</guid>
</item>
<item>
    <title>最基础的python自动化测试</title>
    <link>https://top.zhongtongzttb.com.cn/?post=17</link>
    <description><![CDATA[<p>一、python基础</p>
<p>基本概念</p>
<p>字符集：是一个系统支持的所有抽象字符的集合，计算机中储存的信息都是用二进制数表示的。<br />
字符编码（Character Encoding）：是一套法则，使用该法则能够对自然语言的字符的一个集合（如字母表或音节表），与其他东西的一个集合（如号码或电脉冲）进行配对。即在符号集合与数字系统之间建立对应关系，它是信息处理的一项基本技术。以计算机为基础的信息处理系统则是利用元件（硬件）不同状态的组合来存储和处理信息的。元件不同状态的组合能代表数字系统的数字，因此字符编码就是将符号转换为计算机可以接受的数字系统的数，称为数字代码。<br />
常用的字符集合字符编码<br />
常见字符集名称：ASCII字符集、GB2312字符集、BIG5字符集、GB18030字符集、Unicode字符集等。计算机要准确的处理各种字符集文字，需要进行字符编码，以便计算机能够识别和存储各种文字。<br />
UTF-8（8-bit Unicode Transformation Format）是一种针对Unicode的可变长度字符编码（定长码），也是一种前缀码。它可以用来表示Unicode标准中的任何字符，且其编码中的第一个字节仍与ASCII兼容，这使得原来处理ASCII字符的软件无须或只须做少部份修改，即可继续使用。因此，它逐渐成为电子邮件、网页及其他存储或传送文字的应用中，优先采用的编码。互联网工程工作小组（IETF）要求所有互联网协议都必须支持UTF-8编码。<br />
有时我们看到页面上的乱码，可能就是字符集不一致导致的。<br />
变量(variable)变量就是代表某个数据(值)的名称。python是一种动态类型语言，在赋值的执行中可以绑定不同类型的值，这个过程叫做变量赋值操作，赋值同时确定了变量类型。<br />
静态类型语言是指在编译时变量的数据类型即可确定的语言，多数静态类型语言要求在使用变量之前必须声明数据类型，某些具有类型推导能力的现代语言可能能够部分减轻这个要求.<br />
动态类型语言是在运行时确定数据类型的语言。变量使用之前不需要类型声明，通常变量的类型是被赋值的那个值的类型。</p>
<p>python中变量的定义</p>
<p>1、变量名可以包括字母、数字、下划线，但是数字不能做为开头。例如：name1是合法变量名，而1name就不可以。<br />
2、系统关键字不能做变量名使用<br />
3、除了下划线之个，其它符号不能做为变量名使用<br />
4、Python的变量名是区分大小写的，例如：name和Name就是两个变量名，而非相同变量哦。<br />
5、中文也能定义变量名，单实际当中不这样运用</p>
<p>python的数据类型</p>
<p>1）整型——int——数字<br />
python有5种数字类型，最常见的就是整型int，例如：a = 123 或 b = -123 等号左边是变量名，右边是要赋的值</p>
<p>2）布尔型——bool——用符号==表示<br />
布尔型是一种比较特殊的python数字类型，它只有True和False两种值，它主要用来比较和判断，所得结果叫做布尔值。例如：3==3 给出True，3==5给出False</p>
<p>3）字符串——str——用' '或&quot; &quot;表示<br />
例如：URL='www.iplaypy.com'或者name=&quot;lijing&quot;</p>
<p>4）列表——list——用[ ]符号表示<br />
例如：num=[1,2,3,4]</p>
<p>5）元组——tuple——用( )符号表示<br />
例如：（'d',300）</p>
<p>6）字典——dict——用{ }符号表示<br />
例如：｛'name':'coco','country':'china'｝</p>
<p>实战演练</p>
<p>安装python，安装pycharm编码软件进行编码。</p>
<p>1、hello world！</p>
<p>python中输出函数print函数，字符串和数值类型的可以直接输出，如下</p>
<p>print('hello world')<br />
print(1)<br />
输出内容：</p>
<p>输出字符串内容可以用‘’，也可以用“”，当输出的字符串中包含‘’时，则字符串用“”；当输出的字符串中包含“”号时，则字符串用‘’；当输出的字符串中‘’和“”都包含时，则字符串用‘’‘ ‘’’来输出；如下</p>
<p>print(&quot;你真的很'帅'！&quot;)<br />
print('你真的很&quot;帅&quot;！')<br />
print(''''哇！'你真的很&quot;帅&quot;！''')<br />
输出内容：</p>
<p>输出变量类型</p>
<p>x='hello world!'<br />
print(x)<br />
s=13<br />
print(s)<br />
l=[1,2,3,'p']<br />
print(l)</p>
<p>格式化输出</p>
<p>输出的内容中包含定义的参数时，</p>
<p>name=input('请输入你的姓名：')<br />
time='2017年12月19日'<br />
print('%s欢迎光临！'%name)<br />
输出内容</p>
<p>%字符：标记转换说明符的开始 ，s表示格式转换类型为字符串，f表示十进制浮点数，d表示带符号的十进制整数</p>
<p>当有两个输出参数的使用，在%(参数1，参数2)列出需要传参的参数名</p>
<p>name=input('请输入你的姓名：')<br />
time='2017年12月19日'<br />
print('%s欢迎光临！'%name)<br />
print('%s欢迎光临！时间是：%s'%(name,time))<br />
输出内容：</p>
<p>+的形式进行字符串拼接：</p>
<p>name=input('请输入你的姓名：')<br />
time='2017年12月19日'<br />
print('%s欢迎光临！'%name)<br />
print(name+'欢迎光临！')</p>
<p>输出内容：</p>
<p>可以看到字符串拼接 + 的输出内容与%形式的转换是一样的；</p>
<p>还有一种方式更加简便快捷常用，{}的形式进行传参</p>
<p>name=input('请输入你的姓名：')<br />
time='2017年12月19日'<br />
print('%s欢迎光临！'%name)<br />
print('%s欢迎光临！时间是：%s'%(name,time))<br />
print(name+'欢迎光临！')<br />
print('{}欢迎光临！时间是：{}'.format(name,time))</p>
<p>输出内容：</p>
<p>请输入你的姓名：pei<br />
pei欢迎光临！<br />
pei欢迎光临！时间是：2017年12月19日<br />
pei欢迎光临！<br />
pei欢迎光临！时间是：2017年12月19日</p>
<p>当参数较多时，可能会记忆混乱出现传参错误的情况，此时我们可重新定义一下传参的内容：如下实现方法</p>
<p>name=input('请输入你的姓名：')<br />
time='2017年12月19日'<br />
print('%s欢迎光临！'%name)<br />
print('%s欢迎光临！时间是：%s'%(name,time))<br />
print(name+'欢迎光临！')<br />
print('{}欢迎光临！时间是：{}'.format(name,time))<br />
print('{username}欢迎光临！时间是：{localtime}'.format(username=name,localtime=time))<br />
输出内容：</p>
<p>2、条件判断基本使用方法</p>
<p>语法：</p>
<p>if 条件表达式：</p>
<pre><code>  语句块</code></pre>
<p>例子：</p>
<p>如果成绩达到80分或以上，视为优秀。</p>
<pre><code>   成绩达到60分到80分（不包括80分），视为及格。

   成绩60分以下，视为不及格。</code></pre>
<p>我们输入一个分数，用if语句判断是否能打印出分数所属阶段:</p>
<p>score =input('请输入分数：')<br />
if score &gt;= 80:<br />
print('优秀')<br />
elif score &gt;=60 and score&lt;80:<br />
print('及格')<br />
else:<br />
print('不及格！')<br />
执行上面的语句，输入分数为89，看执行结果</p>
<p>上述结果我们看到执行报错了，str类型的与int类型不能进行比较；</p>
<p>因为score为一个输入类型的变量，而input函数所有形式的输入按字符串处理，如果想要得到其他类型的数据进行强制类型转化，此处我们需要对输入内容强制进行转化，如下</p>
<p>score =int(input('请输入分数：'))<br />
if score &gt;= 80:<br />
print('优秀')<br />
elif score &gt;=60 and score&lt;80:<br />
print('及格')<br />
else:<br />
print('不及格！')<br />
执行上述代码，输入分数为99，查看输出结果</p>
<p>输入分数为78，查看输出结果</p>
<p>输入分数为55，查看输出结果</p>
<p>2、for循环和while循环的基本使用方法</p>
<p>for循环</p>
<p>for something in XXXX:<br />
语句块</p>
<p>即表示对XXXX中的每一个元素，执行某些语句块，XXXX可以是列表，字典，元组，迭代器等等。</p>
<p>如下</p>
<p>for x in range(10):<br />
print('test')<br />
执行查看输出结果，输入了10次test</p>
<p>while循环：</p>
<p>while 条件表达式1：</p>
<pre><code>  语句块</code></pre>
<p>while 循环不会迭代 list 或 tuple 的元素，而是根据表达式判断循环是否结束。while循环会每次判断 条件表达式1 是否为true，如果为true，则执行语句块，否则退出循环。</p>
<p>例如：</p>
<p>count=0<br />
while count&lt;3:<br />
print('哈哈哈')<br />
count+=1<br />
执行看一下结果</p>
<p>结果输出了3次‘哈哈哈’，每一次输入，count+1，直到不满足条件count&lt;3时，退出循环。</p>
<p>continue和break</p>
<p>break：</p>
<p>直接退出整个循环体；</p>
<p>continue：</p>
<p>跳出本次循环，执行下一次循环。</p>
<p>例如上边的例子，我们加上break和continue来看一下结果</p>
<p>for x in range(10):<br />
print('test')<br />
break</p>
<p>执行并查看结果</p>
<p>我们看到for循环中添加break之后，执行一次，遇到break就退出循环了，没有继续循环。</p>
<p>在while中添加continue来试试：</p>
<p>count=0<br />
while count&lt;3:<br />
count += 1<br />
username=input('请输入您的姓名：')<br />
if username=='小王':<br />
print('%s，欢迎光临！'%username)<br />
break<br />
else:<br />
print('您好，您重新输入！')<br />
continue<br />
else:<br />
print('您好，输入次数过多！')<br />
执行上述代码，输入姓名为：ww,查看结果</p>
<p>执行代码，输入姓名为：小王，查看结果</p>
<p>其中，字符串的比较</p>
<p>相等：==</p>
<p>不等于 :=!</p>
<p>小于等于 ：&lt;=</p>
<p>大于等于：&gt;=</p>
<p>我们再来试一个猜数字的例子</p>
<p>Python中的random模块用于生成随机数。下面介绍一下random模块中最常用的几个函数。</p>
<p>random.random</p>
<p>random.random()用于生成一个0到1的随机符点数: 0 &lt;= n &lt; 1.0</p>
<p>random.uniform</p>
<p>random.uniform的函数原型为：random.uniform(a, b)，用于生成一个指定范围内的随机符点数，两个参数其中一个是上限，一个是下限。如果a &gt; b，则生成的随机数n: a &lt;= n &lt;= b。如果 a &lt;b， 则 b &lt;= n &lt;= a。</p>
<p>random.randint</p>
<p>random.randint()的函数原型为：random.randint(a, b)，用于生成一个指定范围内的整数。其中参数a是下限，参数b是上限，生成的随机数n: a &lt;= n &lt;= b</p>
<p>random.randrange</p>
<p>random.randrange的函数原型为：random.randrange([start], stop[, step])，从指定范围内，按指定基数递增的集合中 获取一个随机数。如：random.randrange(10, 100, 2)，结果相当于从[10, 12, 14, 16, ... 96, 98]序列中获取一个随机数。random.randrange(10, 100, 2)在结果上与 random.choice(range(10, 100, 2) 等效。</p>
<p>random.choice</p>
<p>random.choice从序列中获取一个随机元素。其函数原型为：random.choice(sequence)。参数sequence表示一个有序类型。这里要说明 一下：sequence在python不是一种特定的类型，而是泛指一系列的类型。list, tuple, 字符串都属于sequence。</p>
<p>random.shuffle</p>
<p>random.shuffle的函数原型为：random.shuffle(x[, random])，用于将一个列表中的元素打乱。</p>
<p>random.sample</p>
<p>random.sample的函数原型为：random.sample(sequence, k)，从指定序列中随机获取指定长度的片断。sample函数不会修改原有序列。</p>
<p>首先需要导入random模块</p>
<p>import random<br />
random_num=random.randint(1,1999)<br />
print(random_num)<br />
执行查看结果为 736 ，取了一个随机数。</p>
<p>下面来写猜数字的例子：如果7次之内猜出数字，则结束，如果错误，输入超过7次后结束。</p>
<p>import random  # 导入random模块<br />
random_num = random.randint(1, 500)<br />
count = 0<br />
while count &lt; 7:<br />
count += 1<br />
num = int(input('请输入你猜的数字：'))<br />
if num &gt; random_num:<br />
print('你猜的太大了')<br />
continue<br />
elif num &lt; random_num:<br />
print('你猜的太小了')<br />
continue<br />
else:<br />
print('恭喜你猜对了，答案是：%s'%num)<br />
break<br />
执行输入相应的数字，查看结果</p>
<pre><code></code></pre>]]></description>
    <pubDate>Thu, 28 Nov 2024 13:34:46 +0800</pubDate>
    <dc:creator>jm8X08LA</dc:creator>
    <guid>https://top.zhongtongzttb.com.cn/?post=17</guid>
</item>
<item>
    <title>Python Selenium UI自动化测试</title>
    <link>https://top.zhongtongzttb.com.cn/?post=11</link>
    <description><![CDATA[<p>1、搭建自动化测试环境<br />
1.1 安装python<br />
1.2 安装selenium</p>
<h1>安装Selenium的最新版本</h1>
<p>pip install selenium</p>
<h1>安装Selenium指定版本</h1>
<p>pip install selenium==2.53.0<br />
1.3 下载webdriver驱动<br />
以chrome浏览器为例<br />
下载与浏览器版本对应的chrome driver<br />
将下载好的chrome driver 解压，并放至到Python安装路径的根目录 （安装路径随意一个都行）<br />
1.4 第一个自动化测试脚本<br />
打开浏览器<br />
访问百度首页<br />
from selenium import webdriver # 导入webdriver<br />
d = webdriver.Chrome() # 创建浏览器对象，此方法需要提前将webdriver驱动添加到系统环境变量<br />
d.get(‘<a href="https://www.baidu.com">https://www.baidu.com</a>’) # 调用get方法访问百度首页<br />
d.close() # 关闭浏览器<br />
2、webdriver API<br />
2.1 浏览器操作<br />
2.1.1 浏览器最大化<br />
driver.maximize_window()<br />
2.1.2 设置浏览器的宽和高<br />
driver.set_window_size(480,800)<br />
2.1.3 控制浏览器前进、后退<br />
前进： driver.forward()<br />
后退： driver.back()<br />
2.1.4 关闭浏览器<br />
关闭当前窗口： driver.close()<br />
关闭浏览器： driver.quit()<br />
2.1.5 浏览器刷新<br />
driver.refresh()<br />
2.1.6 获取当前URL<br />
driver.current_url<br />
2.1.7 获取当前title<br />
driver.title<br />
2.1.8 浏览器截图<br />
driver.save_screenshot(图片路径)<br />
–路径参数必填<br />
–图片格式必须为png<br />
2.2 元素定位<br />
2.2.1 常见的属性<br />
class：元素的类名<br />
id：元素的唯一id<br />
name：元素名，大部分情况唯一<br />
2.2.2 八大元素定位方法<br />
元素定位和操作是自动化测试的核心部分<br />
一个元素就像一个人，有自己的特征（属性）<br />
webdriver提供了一系列的元素定位方法，常用的有下面几种：<br />
id：根据元素id值<br />
name：根据元素name值<br />
class name：根据元素class值<br />
tag name：根据元素标签名字<br />
link text：根据超链接的文本内容<br />
partial link text：根据超链接的部分文本内容<br />
xpath：根据xpath<br />
css selector：通过css定位<br />
xpath定位<br />
语法<br />
/ ：从根节点选取（绝对路径）<br />
// ：从当前节点选取，不考虑节点的位置（相对路径）<br />
… ：选取当前节点的父节点 搜索框的上两级父节点： //*[@id=‘kw’]/…/…<br />
@ ：选取属性<br />
举例：<br />
相对路径： //div[@class=‘entry-sider-panel’]/section[@class=‘entry-sider-panel__bd’]/div/div[1]<br />
CSS定位<br />
语法</p>
<h1>：选取id属性，#kw</h1>
<p>.：选取class属性<br />
[]：选取其他属性，如：[id=‘xx’]</p>
<blockquote>
<p>:层级选取，如：#form&gt;span&gt;input</p>
</blockquote>
<p>举例：div.entry-sider-panel&gt;section.entry-sider-panel__bd&gt;div&gt;div:nth-child(1)<br />
2.3 元素操作<br />
2.3.1 输入内容<br />
send_keys()<br />
2.3.2 点击元素<br />
click()<br />
2.3.3 清空元素文本内容<br />
clear()<br />
2.3.4 获取元素文本<br />
text<br />
返回的是字符串<br />
2.3.5 获取元素尺寸<br />
size<br />
返回的是字典<br />
2.3.6 获取元素的属性值<br />
get_attribute(‘属性值’) --如id，clas</p>]]></description>
    <pubDate>Mon, 18 Nov 2024 11:45:25 +0800</pubDate>
    <dc:creator>neal1988</dc:creator>
    <guid>https://top.zhongtongzttb.com.cn/?post=11</guid>
</item>
<item>
    <title>Python 接口自动化测试</title>
    <link>https://top.zhongtongzttb.com.cn/?post=10</link>
    <description><![CDATA[<p>一、环境搭建<br />
python +unittest+ requests实现http请求的接口自动化<br />
Python的优势：语法简洁优美, 功能强大, 标准库跟第三方库灰常强大，建议大家事先了解一下Python的基础;<br />
unittest是python的标准测试库，相比于其他测试框架是python目前使用最广的测试框架。<br />
Requests 是用Python语言编写，基于urllib，采用Apache2 Licensed开源协议的HTTP 库。它比urllib 更加方便，可以节约我们大量的工作，完全满足HTTP 测试需求。<br />
在CMD命令行执行命令加载request第三方库：pip install requests<br />
python -m pip install pillow<br />
二、方法<br />
pip安装requests第三方库，然后引入：import requests<br />
引入json标准库，美化json输出：import json<br />
调用requests库中的post方法，会给出所需要的参数,传入上面定义的url和data参数，运行.py文件就执行了post请求。<br />
import requests    #pip安装requests第三方库，然后引入<br />
import json             #引入json标准库，美化json输出</p>
<p>url = '<a href="http://***/account/login">http://***/account/login</a>'<br />
data = {<br />
&quot;username&quot;:&quot;***01&quot;,<br />
&quot;password&quot;:&quot;password&quot;,<br />
}</p>
<p>result = requests.post(url,data).json()  #以json格式输出<br />
print(result)<br />
result = requests.post(url,data).text     #以源码形式输出<br />
print(result)<br />
import requests#引入requests第三方包<br />
import json#引入json包</p>
<p>class Login():<br />
def httprequests(self,url,data,method):#self为类函数的默认函数，放在第一位<br />
if method==&quot;post&quot;:<br />
res=requests.post(url,data)#post请求方法<br />
else:<br />
res=requests.get(url,data)#get请求方法<br />
print(res.text)#以源码形式输出<br />
print(res.json())#以json形式输出</p>
<h1>创建实例，调用函数</h1>
<p>test1=Login()<br />
login_url='<a href="https://www.******/pc/member/sign">https://www.******/pc/member/sign</a>'<br />
login_data={&quot;flag&quot;:&quot;mobile&quot;,<br />
&quot;password&quot;:&quot;f5e05a41724115d076bfb1fd2bd9613e&quot;,<br />
&quot;mobile_phone&quot;:&quot;136<strong>****</strong>&quot;}<br />
login_method='post'<br />
test1.httprequests(login_url,login_data,login_method)</p>]]></description>
    <pubDate>Mon, 18 Nov 2024 11:37:42 +0800</pubDate>
    <dc:creator>neal1988</dc:creator>
    <guid>https://top.zhongtongzttb.com.cn/?post=10</guid>
</item>
<item>
    <title>可可西里的好风景</title>
    <link>https://top.zhongtongzttb.com.cn/?post=6</link>
    <description><![CDATA[<p>青海可可西里国家级自然保护区，位于青海省玉树藏族自治州西北部，昆仑山南麓长江北源地区，与新疆维吾尔自治区、西藏自治区和海西蒙古藏族自治州及玉树州的曲麻莱县接壤。地理位置在东经89°30'~95°05'，北纬33°02'~36°30'之间，南北宽约280千米，东西长200~400千米，面积4.5万平方千米。核心区在34°40'~35°50'N，89°30'~92°30'E之间，面积约2.55万平方千米。 [12]<br />
青海可可西里国家级自然保护区主要是保护藏羚羊、野牦牛、藏野驴、藏原羚等珍稀野生动物，现有高等植物约202种，分属30科102属。以矮小的草本和垫状植物为主，木本植物极少，仅存在个别种类，如匍匐水柏枝、垫状山岭麻黄。200多种植物中，青藏高原特有种和青藏高原至中亚高山、西喜马拉雅和东帕米尔分布的种在区系成分中占主导地位，以及保护区内的众多山体，如昆仑山脉的部分区域。 [1]<br />
2014年11月，青海可可西里申报世界自然遗产工作启动。 [18]2017年7月7日，在波兰克拉科夫举行的第41届世界遗产大会上，青海可可西里经世界遗产委员会一致同意，获准列入《世界遗产名录》，成为中国第51处世界遗产。</p>]]></description>
    <pubDate>Thu, 07 Nov 2024 15:38:53 +0800</pubDate>
    <dc:creator>neal</dc:creator>
    <guid>https://top.zhongtongzttb.com.cn/?post=6</guid>
</item>
<item>
    <title>心情</title>
    <link>https://top.zhongtongzttb.com.cn/?post=5</link>
    <description><![CDATA[<p>世界如此美好，你却如此暴躁</p>]]></description>
    <pubDate>Thu, 07 Nov 2024 14:29:51 +0800</pubDate>
    <dc:creator>neal</dc:creator>
    <guid>https://top.zhongtongzttb.com.cn/?post=5</guid>
</item>
<item>
    <title>你好，内江</title>
    <link>https://top.zhongtongzttb.com.cn/?post=3</link>
    <description><![CDATA[<p>内江是一个历史文化名城</p>]]></description>
    <pubDate>Mon, 04 Nov 2024 10:47:58 +0800</pubDate>
    <dc:creator>neal</dc:creator>
    <guid>https://top.zhongtongzttb.com.cn/?post=3</guid>
</item>
</channel>
</rss>