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解析、错误处理和数据存储机制,该程序能够高效地采集目标数据。在实际开发过程中,还需要根据具体需求进行定制化开发,并注意遵守相关法律法规和网站使用条款。
希望这篇文章对你理解和开发网络爬虫有所帮助!