https://mp.weixin.qq.com/s/pyxnKl7JZ-YHI9PBjzLDGA

取得Token
登录

https://sieportal.siemens.com/en-cn/home
手动取得Token

代码分析
首先,让我们看一下完整代码:

using System;
using System.IO;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using System.Text.Json;
using System.Threading;
using System.Threading.Tasks;

namespace AppSiemens
{
internal class Program
{
staticstring token = “xxxxciOiJSUzI1NiIsImtpZCI6IjY1MUYzOTBCRDVBNkI4MkZCMDBCNzg2QUVFREE2MDE0NzVDMzE4QjRSUzI1NiIsIng1dCI6IlpSODVDOVdtdUMtd0MzaHE3dHBnRkhYREdMUSIsInR5cCI6ImF0K2p3dCJ9.eyJpc3MiOiJodHRwczovL2F1dGguc2llcG9ydGFsLnNpZW1lbnMuY29tIiwibmJmIjoxNzQ3NjA2MjY0LCJpYXQiOjE3NDc2MDYyNjQsImV4cCI6MTc0NzYwOTg2NCwiYXVkIjoiaHR0cHM6Ly9hdXRoLnNpZXBvcnRhbC5zaWVtZW5zLmNvbS9yZXNvdXJjZXMiLCJzY29wZSI6WyJvcGVuaWQiLCJwcm9maWxlIl0sImFtciI6WyJleHRlcm5hbCJdLCJjbGllbnRfaWQiOiJTaWVtZW5zLlNpZVBvcnRhbC5VSSIsInN1YiI6IkI3NEE2OTIxMjU5RDczRkI3RkMyQjIxNzNEMkJEMjYwMjE3OEJFMDdGOEZEMDQyREE5QkQ5RDdDMTVGNTg3QTUiLCJhdXRoX3RpbWUiOjE3NDc2MDYyNjEsImlkcCI6IlNhbWwyIiwidXJuOm9pZDpzc286Y3JlZCI6IndsOTk4MUAxNjMuY29tIiwidXJuOm9pZDpzc286bWFpbCI6IndsOTk4MUAxNjMuY29tIiwidXJuOm9pZDpzc286Z2lkIjoiIiwidXJuOm9pZDpzc286Z2l2ZW5uYW1lIjoiV2FuZyIsInVybjpvaWQ6c3NvOmFwcHN0YXR1cyI6IklNPWFjdGl2ZXxHTUM9YWN0aXZlfFNJT1M9YWN0aXZlfFNJRVBPUlRBTD1hY3RpdmUiLCJ1cm46b2lkOnNzbzp1c2VydHlwZSI6IiIsInVybjpvaWQ6c3NvOmZhbWlseW5hbWUiOiJMaWFuZyIsInVybjpvaWQ6c3NvOmFjY291bnR0eXBlIjoiRXh0ZXJuIiwidXJuOm9pZDpzc286c3NvdWlkIjoiRUZBQzEwQ0YtQ0ZGRS00MTNFLUFGOUUtQkY0NjcwMjg5NUJEIiwibGFzdC1sb2dpbiI6IjIwMjUtMDUtMThUMjI6MTE6MDQgXHUwMDJCMDA6MDAiLCJyb2xlIjoidXNlciIsImluaXRpYWxzIjoiV0wiLCJodHRwOi8vc2NoZW1hcy5hdXRoMC5jb20vYWFsIjoiMSIsInVybjpvaWQ6c3NvOnNpb3NwdCI6InRydWUiLCJzaWQiOiI3NkE3ODREOEIyNUJBREE1N0VFMTMzM0M5QTFDREM1RSIsImp0aSI6IjkwN0I2MzhEQURDNjFERDM2Mjc2MDlGNzk2N0REMDkyIn0.yO_ZcZtjVKBF7TxsUM-acAFUFMwujJsfbtAo7J8WupW4cZ8gBlSg3vOL0-BU15jnyWkAlPgfnCGM4ERtXgHsC4aHv-k-Avr1rGPOl65ZYDZODwnmJEcFJCoEUa_cFuXHU-zxxHznNxHQyasZFzkMfDFhF0WqJs1zWH7nVqsQQKnBrBZwWpL7gnRML7hjrq2UJmfNWThWpoXNjQ2cfsToghsArOZNzyCkdln6L6uy7UCPSmS9A3WsxF71l9skf4ZNWzD4QOOgn8SY300nP2EvccCqAI6slhS1i94l8xeROVua0VfAMTERhxcROK23wWP9cl0BQSuX5APwfgBgw9–QEp88y4lOUQfcD9gS0FK2cTZX-B0yz_pNYqyJ9mpiMZods-kh7RLwpHYXAMtqj4LiCnooSFCBxG47v5WqTH6i4XpDklf9JcJzjUuAzcUJKLxFyggeFzBsKulDvCcqO_GAhjCLPK4t9k-KJhxN7NGtjTp-ox4fLCYWk2Xt_422nySABs5NvkdfGXrLfLDsVt-bn_5K6TgzAG90L_EyXPMaO4TjVZrmv1WWcJ4t3xUTgS1UDN0sKFS0S2vIlmwRzUwiZ3kvNClo5Avf6Ru4ks5MC3uCUcmUI_BojCZ3KIWfMOQ4f-km054Q-PTA-zCvNB0ssg1gM7Rj2WKRW4duZpKAzg”;

    static async Task Main(string[] args)
    {
        Random random = new Random();
        for (int i = 1; i < 100; i++) //这里可以手动改写,或是采取
        {
            await Download(i);
            int delay = random.Next(1000, 3000);
            Thread.Sleep(delay);
        }
        Console.ReadKey();
    }

    private static async Task Download(int page)
    {
        Console.WriteLine($"开始第{page}页");
        // 创建HttpClient实例  
        using HttpClient client = new HttpClient();

        // 设置Bearer Token认证  
        client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
        client.DefaultRequestHeaders.Add("User-Agent", "Apifox/1.0.0 (https://apifox.com)");
        client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("*/*"));
        client.DefaultRequestHeaders.Host = "sieportal.siemens.com";
        client.DefaultRequestHeaders.Connection.Add("keep-alive");

        // 添加Cookie  
        client.DefaultRequestHeaders.Add("Cookie", "idp_login_query_param=display=sup social-off");

        // 使用正确的API端点  
        string url = $"https://sieportal.siemens.com/api/sios/api/Search/SupportContent?region=cn&language=zh&SearchTerm=&SortingOption=CreationDateDesc&Page={page}&PageSize=100";

        try
        {
            // 发送请求  
            HttpResponseMessage response = await client.GetAsync(url);
            response.EnsureSuccessStatusCode();

            // 读取响应内容  
            string jsonContent = await response.Content.ReadAsStringAsync();

            // 解析JSON  
            using JsonDocument doc = JsonDocument.Parse(jsonContent);
            JsonElement root = doc.RootElement;

            // 提取supportContent数组  
            JsonElement supportContent = root.GetProperty("supportContent");

            // 创建一个StringBuilder来存储提取的信息  
            StringBuilder sb = new StringBuilder();

            // 遍历每个内容项  
            foreach (JsonElement item in supportContent.EnumerateArray())
            {
                // 提取需要的字段  
                int entryId = item.GetProperty("entryId").GetInt32();
                string title = item.GetProperty("title").GetString();
                string itemUrl = item.GetProperty("url").GetString();

                // 添加到输出  
                sb.AppendLine($"EntryId: {entryId}");
                sb.AppendLine($"Title: {title}");
                sb.AppendLine($"URL: {itemUrl}");

                // 如果有languages属性,只提取中文(zh)的  
                if (item.TryGetProperty("languages", out JsonElement languages))
                {
                    try
                    {
                        if (languages.GetArrayLength() > 0)
                        {
                            foreach (JsonElement lang in languages.EnumerateArray())
                            {
                                string langCode = lang.GetProperty("languageCode").GetString();
                                if (langCode == "zh")
                                {
                                    string langUrl = lang.GetProperty("url").GetString();
                                    sb.AppendLine($"中文URL: {langUrl}");
                                    break; // 找到中文后就退出循环  
                                }
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine($"发生错误: {ex.Message}--languages");
                    }
                }

                sb.AppendLine("----------------------------");
            }

            // 将结果写入文件  
            string filePath = "siemens_all1.txt";
            File.AppendAllText(filePath, sb.ToString());
            Console.WriteLine($"数据已成功保存到 {filePath}");
        }
        catch (Exception ex)
        {
            Console.WriteLine($"发生错误: {ex.Message}");
        }
    }
}

}

以上代码其实还可以优化。

链接对应的网页如下

核心功能解析
身份认证与请求配置
该爬虫使用JWT token进行身份认证,这是访问西门子API的必要条件:

// 设置Bearer Token认证
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue(“Bearer”, token);
同时,代码也精心配置了HTTP请求头,模拟正常的浏览器访问:

client.DefaultRequestHeaders.Add(“User-Agent”, “Apifox/1.0.0 (https://apifox.com)");
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue(“/“));
client.DefaultRequestHeaders.Host = “sieportal.siemens.com”;
client.DefaultRequestHeaders.Connection.Add(“keep-alive”);

分页请求与反爬策略
程序通过分页机制遍历所有数据:

for (int i = 1; i < 100; i++)
{
await Download(i);
int delay = random.Next(1000, 3000);
Thread.Sleep(delay);
}
注意每次请求之间添加了随机延迟(1-3秒),这是防止被目标网站反爬机制检测的重要策略。

JSON解析与数据提取
采用System.Text.Json命名空间下的工具进行JSON解析:

using JsonDocument doc = JsonDocument.Parse(jsonContent);
JsonElement root = doc.RootElement;

// 提取supportContent数组
JsonElement supportContent = root.GetProperty(“supportContent”);
代码针对每个项目提取了以下信息:

EntryId
标题
URL
中文版URL(如果存在)
数据持久化
使用StringBuilder高效拼接文本内容,最后通过File.AppendAllText方法将数据追加到文本文件:

string filePath = “siemens_all1.txt”;
File.AppendAllText(filePath, sb.ToString());
技术亮点
异步编程
使用async/await模式进行HTTP请求,提高程序效率
错误处理
通过try-catch捕获可能的异常,确保程序稳定运行
资源管理
使用using语句确保HttpClient等资源正确释放
分页采集
实现了分页机制,可以系统性地采集大量数据
反爬措施
请求之间添加随机延迟,降低被反爬系统检测的风险
改进建议
Token管理
当前Token是硬编码的,可以改为从配置文件读取或实现自动登录获取
并发控制
可以实现限制最大并发数的机制,防止请求过于频繁
数据存储
考虑使用数据库替代文本文件,便于后续查询和分析
断点续传
添加记录最后下载页码的功能,支持中断后继续下载
日志记录
引入专业日志框架如NLog或Serilog,更好地管理程序运行信息
实现步骤详解
如果你想自己实现类似的爬虫,可以按照以下步骤进行:

分析目标API
使用浏览器开发者工具或Fiddler等工具分析目标网站的API请求
获取认证信息
登录目标网站,获取必要的认证信息(Token、Cookie等)
构建请求
使用HttpClient配置请求头和参数
处理响应
解析JSON或HTML响应,提取所需数据
实现分页
设计分页逻辑,遍历所有数据
添加反爬策略
添加随机延迟,模拟真实用户行为
错误处理
完善异常处理,确保程序稳定性
数据存储
选择合适的方式存储采集的数据
注意事项
合法合规
在进行网络爬虫开发时,请确保遵守目标网站的使用条款和robots.txt规定
请求频率
控制请求频率,避免对目标服务器造成过大负担
数据安全
注意保护采集的数据,特别是包含敏感信息的数据
Token安全
避免在公开场合分享认证Token,防止账号被盗用
总结
本文详细分析了一个用C#编写的西门子支持内容爬虫程序。通过合理的HTTP请求配置、JSON解析、错误处理和数据存储机制,该程序能够高效地采集目标数据。在实际开发过程中,还需要根据具体需求进行定制化开发,并注意遵守相关法律法规和网站使用条款。

希望这篇文章对你理解和开发网络爬虫有所帮助!

文档更新时间: 2025-05-21 09:15   作者:admin