1. 程式人生 > >C#爬取微博文字、圖片、視訊(不使用Cookie)

C#爬取微博文字、圖片、視訊(不使用Cookie)

前兩天在網上偶然看到一個大佬OmegaXYZ寫的文章,Python爬取微博文字與圖片(不使用Cookie) 

於是就心血來潮,順手擼一個C#版本的。

其實原理也很簡單,現在網上大多數版本都需要Cookie來獲取微博資料。但是微博之前不是出了PWA版本嘛,就是通過這個版本,可以不用Cookie,來順利獲取微博資料。

 

關於使用Cookie與不使用Cookie的區別,dataabc大佬也有說明,下面是原文引用

對於大部分微博使用者,不新增cookie也可以獲取其使用者資訊和大部分微博,不同的微博獲取比例不同。以2020年1月2日迪麗熱巴的微博為例,
此時她共有1085條微博,在不新增cookie的情況下,可以獲取到1026條微博,大約佔全部微博的94.56%,而在新增cookie後,可以獲取全部微博。
其他使用者類似,大部分都可以在不新增cookie的情況下獲取到90%以上的微博,在新增cookie後可以獲取全部微博。
具體原因是,大部分微博內容都可以在移動版匿名獲取,少量微博需要使用者登入才可以獲取,所以這部分微博在不新增cookie時是無法獲取的。
有少部分微博使用者,不新增cookie可以獲取其微博,無法獲取其使用者資訊。對於這種情況,要想獲取其使用者資訊,是需要cookie的。

 

dataabc大佬,也是用萬能的Python寫了兩個版本,一個是需要Cookie,一個是不需要Cookie的。

而且使用方法寫的非常詳細。有需要的可以去Github膜拜。

這裡貼一下我親自執行的結果:

 

 

 

 

而開頭提到OmegaXYZ大佬,也是在他自己的版本上更上一層,給Python程式碼加上了GUI介面,更適合大眾小白使用者。

原文地址:python微博爬蟲GUI程式

 

 

 

 

 

 

 

 

好了,介紹完大佬們寫的作品,接下來就說一下我自己的C#版本吧。

由於我在爬蟲領域屬於純小白,一竅不通,所以並不懂什麼爬蟲(Spider)、反爬蟲(Anti-Spider)、反反爬蟲(Anti-Anti-Spider)。

不過在爬蟲與反爬蟲的鬥爭中,爬蟲一定會勝利的,因為爬蟲會進化為和真實使用者一模一樣的行為。

 

接下載我寫的程式碼,是沒有加入反反爬蟲的,建議一跑起來,就立即終止,或者,加入一個Task.Delay(1000)之類的延時。

不要爬取的太快,容易被微博遮蔽ip!!!

不要爬取的太快,容易被微博遮蔽ip!!!

不要爬取的太快,容易被微博遮蔽ip!!!

即使被遮蔽也別慌,過一段時間就會恢復。

 

 

1. 獲取使用者的uid,構建基礎url

uid即微博使用者的唯一標識id,具體如何獲取uid,可以檢視前面二位大佬寫的教程,這並不是本文的重點。

基礎url是指我們通過這個,可以獲取微博使用者的基本資訊,以及一個非常重要的欄位:containerid

只有通過containerid才可以獲取使用者發的微博。

一個完整的例項Url:

string strBaseUrl = "https://m.weibo.cn/api/container/getIndex?type=uid&value=1197191492";

 

 

2.通過HttpClient獲取containerid

通過HttpClient,把strBaseUrl和uid拼接起來,我們就可以得到返回的json資料。

而我們需要的containerid就是在 res?.data?.tabsInfo?.tabs 下面。

            var res = await HttpHelper.GetAsync<UserSummary>(strBaseUrl);
            if(res != null && res?.ok == 1)
            {
                if(res?.data?.tabsInfo?.tabs != null)
                {
                    foreach(var item in res?.data?.tabsInfo?.tabs)
                        if(item.tab_type == "weibo")
                        {
                            strContainerId = item.containerid;
                            break;
                        }
                }
            }

 

 

 

 

 

3. 拼接基礎url、containerid、page獲取分頁微博資訊。

拼接上面的引數,一個完整的示例:

https://m.weibo.cn/api/container/getIndex?type=uid&value=1197191492&containerid=1076031197191492&page=1

 

這裡我通過自己的理解區分了三種微博型別:

①包含圖片:

    判斷 home?.data?.cards[j].mblog.pics != null

②包含視訊:

    判斷 home?.data?.cards[j].mblog.page_info != null && home?.data?.cards[j].mblog.page_info.type == "video"

③文字:

   不是①和②的

不過應該還有其他的型別,我還沒仔細分析。

 

C#程式碼:

string strWeiboUrl = strBaseUrl + "&containerid=" + strContainerId + "&page=";
            int i = 1;
            while(true)
            {
                var home = await HttpHelper.GetAsync<UserHome>(strWeiboUrl + i.ToString());
                if (home != null && home?.ok == 1 && home?.data != null && home?.data?.cards?.Count > 0)
                {
                    Debug.WriteLine("---第" + i + "頁---");

                    for (int j = 0; j <= home?.data?.cards.Count - 1; j++)
                    {
                        if(home?.data?.cards[j].card_type == 9)
                        {
                            Debug.WriteLine("第" + (j + 1) + "條微博---");
                            Debug.WriteLine("微博原始地址:" + home?.data?.cards[j].scheme);
                            if(home?.data?.cards[j].mblog != null)
                            {
                                Debug.WriteLine("釋出日期:" + home?.data?.cards[j].mblog.created_at
                                    + ";轉發數:" + home?.data?.cards[j].mblog.reposts_count
                                    + ";評論數:" + home?.data?.cards[j].mblog.comments_count
                                    + ";點贊數:" + home?.data?.cards[j].mblog.attitudes_count);
                                if (!string.IsNullOrEmpty(home?.data?.cards[j].mblog.source))
                                    Debug.WriteLine("來自:" + home?.data?.cards[j].mblog.source);
                                Debug.WriteLine("微博內容:" + home?.data?.cards[j].mblog.text);
                                if(home?.data?.cards[j].mblog.pics != null)
                                {
                                    Debug.WriteLine("微博型別:picture");
                                    foreach (var item in home?.data?.cards[j].mblog.pics)
                                        Debug.WriteLine(item.large.url);
                                }
                                else if(home?.data?.cards[j].mblog.page_info != null && home?.data?.cards[j].mblog.page_info.type == "video")
                                {
                                    Debug.WriteLine("微博型別:" + home?.data?.cards[j].mblog.page_info.type);
                                    Debug.WriteLine(home?.data?.cards[j].mblog.page_info.media_info.mp4_hd_url);
                                }
                                else
                                {
                                    Debug.WriteLine("微博型別:text");
                                }

                                //轉發的還是原創的
                                if(home?.data?.cards[j].mblog.retweeted_status == null)
                                {
                                    Debug.WriteLine("原創的微博");
                                }
                                else
                                {
                                    Debug.WriteLine("轉發的微博");
                                    Debug.WriteLine("原文作者:" + home?.data?.cards[j].mblog.retweeted_status.user.screen_name);
                                    Debug.WriteLine("原文內容:" + home?.data?.cards[j].mblog.retweeted_status.text);
                                }
                            }
                            Debug.WriteLine("");
                        }
                    }

                    i++;
                    Debug.WriteLine("");
                    Debug.WriteLine("");
                    Debug.WriteLine("");
                }
                else
                    break;
            }

 

 

4. 最終效果

執行後,記得趕快停掉,別爬太多資料,容易被封。

後續我會研究如使用反反爬蟲機制,防止被封。

&n