尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

Crawl4AI 中的 SSL 证书抓取与导出:SSLCertificate 类完整实战指南

Crawl4AI 中的 SSL 证书抓取与导出:SSLCertificate 类完整实战指南 Crawl4AI 中的 SSL 证书抓取与导出SSLCertificate 类完整实战指南【免费下载链接】crawl4ai Crawl4AI: Open-source LLM Friendly Web Crawler Scraper. Dont be shy, join here: https://discord.gg/jP8KfhDhyN项目地址: https://gitcode.com/GitHub_Trending/craw/crawl4ai本篇围绕 Crawl4AI 的 SSLCertificate 类展开讲解如何在一次爬取中通过fetch_ssl_certificateTrue自动获取目标站点的 TLS 证书如何读取 issuer、subject、有效期与 SHA-256 指纹等关键属性以及如何将证书导出为 JSON、PEM、DER 三种格式。读完后你可以独立完成“抓取 → 读取 → 导出”的完整链路并理解 Crawl4AI 内部从CrawlerRunConfig到CrawlResult的实现细节。1. SSLCertificate 的定位与实现位置SSLCertificate是一个用于封装 TLS 证书数据的便捷类支持多种格式PEM、DER、JSON导出。在 Crawl4AI 中它被集成到爬取结果中只要在 CrawlerRunConfig 中设置fetch_ssl_certificateTrue爬取完成后result.ssl_certificate就会是一个SSLCertificate实例。类的完整实现位于 crawl4ai/ssl_certificate.py。从源码结构看它有几个值得注意的设计# crawl4ai/ssl_certificate.py 核心结构 class SSLCertificate(dict): Represents an SSL certificate with methods to export in various formats. Main Methods: - from_url(url, timeout10) - to_json(filepathNone) - to_pem(filepathNone) - to_der(filepathNone) Common Properties: - issuer - subject - valid_from - valid_until - fingerprint 继承自dict实例本身就是一份可序列化的字典解析后的证书字段因此可以直接用json.dumps序列化这也是它能平滑嵌入 Pydantic 模型CrawlResult/AsyncCrawlResponse而不报类型错误的原因之一models.py 中配置了arbitrary_types_allowedTrue。依赖 pyOpenSSL 解析底层使用OpenSSL.crypto.load_certificate(FILETYPE_ASN1, ...)将二进制证书解析为可读字段ssl_certificate.py。构造函数__init__(cert_info)会先经_decode_cert_data()递归处理字节数据bytes 优先按 UTF-8、失败则按 latin-1 解码再以解码后的字典初始化 dict 部分ssl_certificate.py。2. 在爬取中启用证书抓取2.1 配置参数fetch_ssl_certificate在 async_configs.py 中CrawlerRunConfig与BrowserConfig均声明了该参数类型为bool默认值为Falseconfig CrawlerRunConfig( fetch_ssl_certificateTrue, # 启用后爬取时会抓取目标站点的 TLS 证书 cache_modeCacheMode.BYPASS, # 绕过缓存确保拿到新鲜数据 )该参数在CrawlerRunConfig.__init__中被赋值async_configs.py并纳入序列化输出async_configs.py意味着它在配置匹配与调试日志中同样可见。2.2 内部调用链源码级印证开启该选项后证书抓取的完整数据流如下每一步都能在源码中对应到具体位置抓取入口async_crawler_strategy.py 中在页面导航前判断配置并同步抓取证书# Get SSL certificate information if requested and URL is HTTPS ssl_cert None if config.fetch_ssl_certificate: ssl_cert SSLCertificate.from_url(url)挂到响应对象AsyncCrawlResponse构造时传入ssl_certificatessl_certasync_crawler_strategy.py。回填到最终结果async_webcrawler.py 中执行crawl_result.ssl_certificate async_response.ssl_certificate最终落到CrawlResult.ssl_certificate字段models.py类型为Optional[SSLCertificate]。也就是说抓取的时机在page.goto之前、走的是独立的原生 socket 连接不经浏览器因此即使页面本身加载失败只要 socket 握手成功ssl_certificate仍然可能拿到证书反之若握手/解析失败from_url会返回Noneresult.ssl_certificate即为空代码中需要判空处理。3. 三种构造/获取方式3.1from_url(url, timeout10)—— 主力入口从 URL 抓取证书连接443 端口。内部实现ssl_certificate.py要点hostname urlparse(url).netloc if : in hostname: hostname hostname.split(:)[0] context ssl.create_default_context() with socket.create_connection((hostname, 443), timeouttimeout) as sock: with context.wrap_socket(sock, server_hostnamehostname) as ssock: cert_binary ssock.getpeercert(binary_formTrue) x509 OpenSSL.crypto.load_certificate( OpenSSL.crypto.FILETYPE_ASN1, cert_binary ) # 组装 subject / issuer / version / serial_number / # not_before / not_after / fingerprint(sha256) / # signature_algorithm / raw_cert(base64) / extensions值得注意的源码事实端口固定为 443socket.create_connection((hostname, 443), ...)因此非标准 HTTPS 端口的站点不在其覆盖范围内。默认校验上下文源码使用ssl.create_default_context()其中注释掉的check_hostname False/verify_mode CERT_NONEssl_certificate.py并未启用。可以推断对于自签名或信任链异常的站点握手会抛出SSLCertVerificationError被捕获后打印告警并返回Nonessl_certificate.py——这是排错时需要首先确认的点。错误处理DNS 解析失败socket.gaierror、超时socket.timeout均返回None并打印原因不会向上抛出异常中断爬取。直接调用的最小示例from crawl4ai.ssl_certificate import SSLCertificate cert SSLCertificate.from_url(https://example.com) if cert: print(Fingerprint:, cert.fingerprint)3.2from_file(file_path)与from_binary(binary_data)参考文档 docs/md_v2/advanced/ssl-certificate.md 中还列出了从本地文件ASN.1/DER和原始二进制构造的用法cert SSLCertificate.from_file(/path/to/cert.der) # 本地证书文件 cert SSLCertificate.from_binary(raw_bytes) # 从 socket 等来源捕获的原始字节需要说明的是当前仓库版本的 ssl_certificate.py 中仅实现了from_url这一个静态构造方法from_file/from_binary在参考文档中被列出但在当前源码中并未落地。若手头已有 DER 字节数据可以参照from_url内部的OpenSSL.crypto.load_certificate 字段组装逻辑自行补一段等价解析构造出的cert_info字典可直接喂给SSLCertificate(cert_info)构造函数。4. 常用属性直接读取证书关键字段拿到SSLCertificate实例例如爬取后的result.ssl_certificate后可通过属性读取属性类型说明底层字段issuerdict颁发者如{CN: My Root CA, O: ...}issuersubjectdict主体如{CN: example.com, O: ExampleOrg}subjectvalid_fromstrNotBefore 生效时间ASN.1/UTC 格式not_beforevalid_untilstrNotAfter 失效时间not_afterfingerprintstrSHA-256 摘要小写十六进制如d14d2e...fingerprint这些属性定义在 ssl_certificate.py本质是对内部字典的安全self.get()访问缺失字段时返回空值而非抛错。由于类继承自dict除上述属性外from_url组装的完整字段也可通过字典方式直接访问ssl_certificate.pyversion、serial_numberhex(...)形式、signature_algorithm、raw_cert原始证书的 Base64 编码以及extensions扩展名/值列表。由于继承 dictjson.dumps(cert)即可得到完整导出结果repr()也会输出可读摘要例如SSLCertificate Subjectexample.com Issuer...ssl_certificate.py。5. 导出方法JSON / PEM / DER三个导出方法签名一致——filepathNone时返回内容字符串或字节传入路径时写入磁盘并返回None。5.1to_json(filepathNone)→Optional[str]返回包含解析字段的 JSON 字符串indent2, ensure_asciiFalse提供filepath则写盘。实现见 ssl_certificate.py。json_data cert.to_json() # 返回 JSON 字符串 cert.to_json(certificate.json) # 写文件返回 None5.2to_pem(filepathNone)→Optional[str]将内部的 Base64raw_cert解码还原为 ASN.1 字节经OpenSSL.crypto.dump_certificate(FILETYPE_PEM, ...)转为标准 PEM 文本ssl_certificate.py适合 web 服务器场景使用。转换异常时打印错误并返回None。pem_str cert.to_pem() # 内存中的 PEM 字符串 cert.to_pem(/path/to/cert.pem) # 保存到文件5.3to_der(filepathNone)→Optional[bytes]返回原始 DER二进制 ASN.1字节即raw_cert的 Base64 解码结果ssl_certificate.py适合 Java 等需要 DER 格式的系统。der_bytes cert.to_der() cert.to_der(certificate.der)5.4 关于export_as_text()的说明参考文档中提到“若看到export_as_text()这类方法通常返回 OpenSSL 风格的文本表示”。需要澄清当前仓库源码中并未实现该方法现有实现只提供上述三种导出。如果需要人工可读的文本检查最直接的方式是print(cert.to_pem())或结合to_json()输出字段查看。6. 完整可运行示例仓库内提供了完整示例 docs/examples/ssl_example.py核心流程如下可直接复制运行前提是先安装依赖crawl4aiimport asyncio import os from crawl4ai import AsyncWebCrawler, CrawlerRunConfig, CacheMode async def main(): tmp_dir tmp os.makedirs(tmp_dir, exist_okTrue) config CrawlerRunConfig( fetch_ssl_certificateTrue, cache_modeCacheMode.BYPASS # 绕过缓存确保获取新鲜数据 ) async with AsyncWebCrawler() as crawler: result await crawler.arun(https://example.com, configconfig) if result.success and result.ssl_certificate: cert result.ssl_certificate # 1. 基本字段 print(Issuer CN:, cert.issuer.get(CN, )) print(Valid until:, cert.valid_until) print(Fingerprint:, cert.fingerprint) # 2. 三种格式导出 cert.to_json(os.path.join(tmp_dir, certificate.json)) cert.to_pem(os.path.join(tmp_dir, certificate.pem)) cert.to_der(os.path.join(tmp_dir, certificate.der)) if __name__ __main__: asyncio.run(main())示例输出形如Certificate Information: Issuer: 颁发者 CN Valid until: NotAfter 时间 Fingerprint: sha256 十六进制指纹 Certificate exported to: - JSON: tmp/certificate.json - PEM: tmp/certificate.pem - DER: tmp/certificate.der注意两点判断result.success and result.ssl_certificate是必要的因为证书抓取失败超时、校验失败等时该字段为None且不影响爬取本身的成败使用CacheMode.BYPASS可避免命中缓存时拿到旧的证书对象。7. 注意事项与最佳实践综合参考文档与源码实现使用SSLCertificate时建议关注超时控制from_url默认timeout10秒socket 连接超时慢网络下会打印 Connection timed out 并返回NoneCrawl4AI 内部调用时未显式传 timeout即使用该默认值async_crawler_strategy.py。只抓取解析、不做信任校验该类只负责获取并解析证书不验证证书链或信任库参考文档 Notes 第 3 条。合规性判断是否过期、是否匹配域名信任链需要调用方基于valid_until、subject等字段自行完成。默认上下文带来隐性限制如第 3.1 节所述from_url使用默认校验上下文且端口固定 443自签名站点与非标准端口场景可能取不到证书如需在这些场景下工作可基于ssl.create_default_context()自行放宽校验并复用OpenSSL.crypto的解析逻辑。二进制格式证书以 ASN.1DER形式加载后由OpenSSL.crypto再解析raw_cert字段保存其 Base64 形式因此任何导出方法都以它为还原来源。集成方式日常使用只需在CrawlerRunConfig中设置fetch_ssl_certificateTrueCrawlResult.ssl_certificate会自动构建无需手动调用from_url。导出选型to_json适合入库分析与程序化比对指纹、有效期to_pem适合交给 web 服务器生态to_der适合 Java 等 JVM 生态三者均可直接传文件路径落盘。8. 小结SSLCertificatecrawl4ai/ssl_certificate.py是抓取并导出目标站点 TLS 证书的便捷类继承自dict因而天然支持 JSON 序列化。典型用法是在CrawlerRunConfig中设置fetch_ssl_certificateTrue爬取后从CrawlResult.ssl_certificate读取实例models.py。类提供issuer/subject/valid_from/valid_until/fingerprint五个常用属性以及to_json/to_pem/to_der三种导出方式可快速支撑加密合规检查、证书巡检与变更监测等场景。延伸阅读仓库内路径类实现crawl4ai/ssl_certificate.py配置参数定义与序列化crawl4ai/async_configs.py爬取策略中的抓取调用crawl4ai/async_crawler_strategy.py结果回填逻辑crawl4ai/async_webcrawler.py数据模型字段crawl4ai/models.py官方示例脚本docs/examples/ssl_example.py【免费下载链接】crawl4ai Crawl4AI: Open-source LLM Friendly Web Crawler Scraper. Dont be shy, join here: https://discord.gg/jP8KfhDhyN项目地址: https://gitcode.com/GitHub_Trending/craw/crawl4ai创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表