我目前正在嘗試使用其公共API獲取大量關於維基百科以外的視頻遊戲的數據。我已經得到了一些方法。我目前可以獲得我需要的所有pageid
及其相關文章title
。但後來我需要獲得他們的唯一標識符(Qxxxx,其中x是數字),這需要相當長一段時間...可能是因爲我必須爲每個標題(有22031)進行單個查詢,或者因爲我不瞭解Wikipedia查詢。當製作許多Http請求時,緩衝區大小不足或隊列滿了
所以我想「爲什麼不一次只做多個查詢?」所以我開始研究這個問題,但我在標題中遇到了這個問題。程序運行一段時間後(通常3-4分鐘)大約一分鐘過去,然後應用程序崩潰,標題中出現錯誤。我想這是因爲我的做法是隻壞:
ConcurrentBag<Entry> entrybag = new ConcurrentBag<Entry>(entries);
Console.WriteLine("Getting Wikibase Item Ids...");
Parallel.ForEach<Entry>(entrybag, (entry) =>
{
entry.WikibaseItemId = GetWikibaseItemId(entry).Result;
});
這裏是調用的方法:
async static Task<String> GetWikibaseItemId(Entry entry)
{
using (var client = new HttpClient(new HttpClientHandler { AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate }))
{
client.BaseAddress = new Uri("https://en.wikipedia.org/w/api.php");
entry.Title.Replace("+", "Plus");
entry.Title.Replace("&", "and");
String queryString = "?action=query&prop=pageprops&ppprop=wikibase_item&format=json&redirects=1&titles=" + entry.Title;
HttpResponseMessage response = await client.GetAsync(queryString);
response.EnsureSuccessStatusCode();
String result = response.Content.ReadAsStringAsync().Result;
dynamic deserialized = JsonConvert.DeserializeObject(result);
String data = deserialized.ToString();
try
{
if (data.Contains("wikibase_item"))
{
return deserialized["query"]["pages"]["" + entry.PageId + ""]["pageprops"]["wikibase_item"].ToString();
}
else
{
return "NONE";
}
}
catch (RuntimeBinderException)
{
return "NULL";
}
catch (Exception)
{
return "ERROR";
}
}
}
和公正的良好措施,這裏是入口類:
public class Entry
{
public EntryCategory Category { get; set; }
public int PageId { get; set; }
public String Title { get; set; }
public String WikibaseItemId { get; set; }
}
任何人都可能幫忙嗎?我只需要改變我如何查詢或其他東西?
將同時運行的查詢數量限制爲合理數量,如10,而不是22k – dlatikay
崩潰是因爲服務器不喜歡查詢。通過將查詢放入網頁的網址來手動嘗試查詢。你的申請只是3-4分鐘後超時。如果您獲得文章的標題,則還應該能夠同時獲取該網址。然後通過URL檢索文章。 – jdweng
@dlatikay我會試試這個! – OmniOwl