天天看點

百度網盤資源搜尋器

1 寫在前面

最近想要在百度網盤裡面搜尋一些pdf資源,打開以前儲存的一個專門搜尋百度網盤資源的頁面

so.baiduyun.me

,頁面轉了好久,終于出來,但是出現的卻是Error 522,連結失效了。最後,在網上找到一個可以用的位址

http://pan.java1234.com/

,這個位址确實可以搜尋百度網盤資源,但是廣告超級多,稍有不慎,就進入了一個廣告頁面,神煩。當時就想能不能尋找到這個網頁中資源搜尋的位址,然後自己根據這個位址來模拟請求,進而獲得查詢結果。打開浏覽器的調試工具,随意輸入一個關鍵字進行查詢,點選查詢,然後進行分析。分析發現了一個url請求傳回的正是百度網盤搜尋結果,資料是json格式。找到了這個擷取搜尋結果url之後就好辦了。我們可以完全自己寫一個Winform界面,然後通過這個url去模拟請求,擷取結果,這樣就沒有廣告了,想怎麼弄就怎麼弄,下面介紹一下,如何完成這一系列的過程。

2 分析

2.1 擷取請求頭資訊

實作這個程式的關鍵就是如何擷取

http://pan.java1234.com/

百度網盤搜尋結果的url,首先我們打開這個頁面,啟動浏覽器調試,然後随意輸入一個關鍵字,點選查詢。

百度網盤資源搜尋器

上圖我們可以看到,有一個請求url,傳回來的結果就是頁面上顯示的搜尋結果。我們可以看看它的請求位址以及請求頭資訊。

百度網盤資源搜尋器

通過檢視headers面闆可以知道請求資訊如下:

  • 請求位址:http://pan1234.com/server3?jsoncallback=jQuery19109864917922941505_1478436979648&q=win7&start=0&_=1478436979649
  • User-Agent:Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.102 Safari/537.36
  • Reference:http://pan.java1234.com/result2.jsp?wp=0&op=0&ty=gn&q=win7
  • Host:pan1234.com

知道請求位址,user-agent,host,referer請求頭資訊,我們就可以構造出一個搜尋資源的請求,現在我們來分析一下這個請求位址的特點,這個請求位址有一個查詢參數

q=win7

,而我們知道先前在搜尋框裡面輸入的關鍵字就是win7,由此可以判斷,該查詢參數代表的搜尋關鍵字。我們可以把這個請求位址在浏覽器中打開,然後去去更改這些查詢參數,來分析這些查詢參數各有什麼作用。

經過分析,請求位址中的q參數代表的是搜尋關鍵字;start參數代表的是搜尋頁面,一共有10頁,0代表第一頁,10代表第二頁,···,90代表第十頁,該網頁最高顯示100條資源結果;而最後的&_=1478436979649可以删掉,在請求中沒有實質的作用。

2.2 分析傳回的搜尋結果格式

經過2.1節分析,我們知道搜尋結果的url位址,現在我們随意的構造一個如下。

http://pan1234.com/server3?jsoncallback=jQuery19109864917922941505_1478436979648&q=win7&start=0
           

在浏覽器中顯示的效果如下:

百度網盤資源搜尋器

我們可以知道搜尋結果是以json字元串的格式傳回的。傳回的是一個對象數組,每個資源對象都包含了

title

,

content

unescapedUrl

三個屬性。

知道了傳回的json格式結構,我們就可以在c#中建立相對應的類,然後将這些json資料經過預處理,之後便可以反序列化成為相對應的對象。

3.程式實作

下面将貼出實作該程式的關鍵代碼,源代碼可以到本文章的末尾自行下載下傳。

3.1 資料實體類

public class SearchResult
{
    public BDWPResource[] resources { get; set; }
}

public class BDWPResource
{
    public string title { get; set; }
    public string content { get; set; }
    public string unescapedUrl { get; set; }
}
           

3.2 資料請求及預處理

class HttpHelper
{
    static readonly string urlTemplate = "http://pan1234.com/server3?jsoncallback=jQuery191042552483269501273_1478315152726&q={0}&start={1}";
    public static SearchResult Requset(string key, string start)
    {
        string url = string.Format(urlTemplate, key, start);
        HttpWebRequest httpRequest = (HttpWebRequest)WebRequest.Create(url);
        httpRequest.Accept = "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8";
        httpRequest.UserAgent = "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.102 Safari/537.36";
        httpRequest.Host = "pan1234.com";
        httpRequest.Referer = "http://pan.java1234.com/result.jsp?wp=0&op=0&ty=gn&q=" + Uri.EscapeUriString(key);
        try
        {
            HttpWebResponse httpResponse = (HttpWebResponse)httpRequest.GetResponse();
            Stream s = httpResponse.GetResponseStream();
            StreamReader sr = new StreamReader(s);
            string jsonString = sr.ReadToEnd();
            string jsonProcessed = null;
            if ((jsonProcessed = JsonPreProcessing(jsonString)) != null)
            {
                SearchResult searchResult = UtilityClass.GetObject<SearchResult>(jsonProcessed);
                return searchResult;
            }
            return null;
        }
        catch
        {
            return null;
        }
    }

    public static string JsonPreProcessing(string jsonString)
    {
        int startIndex = jsonString.IndexOf("(");
        if (startIndex > 0)
        {
            string json = jsonString.Substring(startIndex + 1);
            return "{\"resources\":" + json.Remove(json.Length - 3) + "}";
        }
        else
        {
            return null;
        }
    }
}
           

3.3 json資料反序列化對象

class UtilityClass
{
    public static T GetObject<T>(string json)
    {
        DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(T));
        MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes(json));
        T obj = (T)serializer.ReadObject(ms);
        return obj;
    }
}
           

3.4 界面

界面設計如下:

百度網盤資源搜尋器

将網絡請求的代碼放到任務線程中進行執行。代碼如下:

Thread thread = new Thread(() =>
{
    for (int i = 0; i < 100; i += 10)
    {
        if (isSearch)
        {
            SearchResult sr = HttpHelper.Requset(key, i.ToString());
            if (sr != null)
            {
                foreach (BDWPResource resource in sr.resources)
                {
                    BindResource(resource);
                }
            }
        }
        else break;
    }
    //搜尋完成
    SearchOver();
});
thread.IsBackground = true;
thread.Start();

//綁定資料代碼
private void BindResource(BDWPResource resource)
{
    string title = resource.title.Replace("</b>", "").Replace("<b>","");
    string content = resource.content.Replace("</b>", "").Replace("<b>", "");

    this.Invoke(new Action<string, string, string>((tle, ctt, url) => 
    {
        this.dataGridView1.Rows.Add(tle, ctt, url);
        this.lblResult.Text = (Int32.Parse(this.lblResult.Text) + 1).ToString();
        this.pgsBar.Value++;
    }), title, content, resource.unescapedUrl);
}
//搜尋完成
private void SearchOver()
{
    this.Invoke(new Action(() => {
        this.btnSearch.Text = "開始搜尋";
        this.btnSearch.Enabled = true;
        this.btnStop.Enabled = false;
        this.isSearch = true;
    }));
}
           

3.5 程式運作結果

百度網盤資源搜尋器
百度網盤資源搜尋器

4 結論

該程式搜尋速度有時候比較慢,有時間快,剛開始點選搜尋一般都要等一會才有結果,可能有網絡延遲的原因。但發現搜尋一會還沒結果的時候,可以先停止搜尋,然後再點選開始搜尋,就會有搜尋結果出來了。

5 資源

源代碼下載下傳連結:http://download.csdn.net/download/mingge38/9674694

繼續閱讀