抓取百万知乎用户信息之HttpHelper的迭代之路

什么是Httphelper?

httpelpers是一个封装好拿来获取网络上资源的工具类。因为是用http协议,故取名httphelper。

httphelper出现的背景

使用WebClient可以很方便获取网络上的资源,例如

              WebClient client = new WebClient();
            string html=   client.DownloadString("https://www.baidu.com/");

这样就可以拿到百度首页的的源代码,由于WebClient封装性太强,有时候不大灵活,需要对底层有更细致的把控,这个时候就需要打造自己的网络资源获取工具了;

HttpHelper初级

现在着手打造自己的下载工具,刚开始时候长这样

public class HttpHelp
  {
        public static string DownLoadString(string url)
        {
               string Source = string.Empty;
         HttpWebRequest request= (HttpWebRequest)WebRequest.Create(url);         using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())         {             using (Stream stream = response.GetResponseStream())            {                using (StreamReader reader = new StreamReader(stream, Encoding.UTF8))                       {                          Source = reader.ReadToEnd();                         }              }         }        return  Source;      } }程序总会出现各种异常的,这个时候加个Try catch语句
public class HttpHelp
  {
        public static string DownLoadString(string url)
        {

           string Source = string.Empty;
           try{
                HttpWebRequest request= (HttpWebRequest)WebRequest.Create(url);
                using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
                {
                    using (Stream stream = response.GetResponseStream())
                     {
                        using (StreamReader reader = new StreamReader(stream, Encoding.UTF8))
                       {
                          Source = reader.ReadToEnd();
                       }
                    }
                }
           }
          catch          {
              Console.WriteLine("出错了,请求的URL为{0}", url);
          }
        return  Source;
      }
 }

请求资源是I/O密集型,特别耗时,这个时候需要异步

 public static async Task<string> DownLoadString(string url)
        {
            return await Task<string>.Run(() =>
            {
                string Source = string.Empty;
                try
                {
                    HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
                    using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
                    {
                        using (Stream stream = response.GetResponseStream())
                        {
                            using (StreamReader reader = new StreamReader(stream, Encoding.UTF8))
                            {
                                Source = reader.ReadToEnd();
                            }
                        }
                    }
                }
                catch
                {
                    Console.WriteLine("出错了,请求的URL为{0}", url);
                }
                return Source;
            });

        }

 HttpHelper完善       
为了欺骗服务器,让服务器认为这个请求是浏览器发出的

   request.UserAgent = "Mozilla/5.0 (Windows NT 10.0; WOW64; rv:49.0) Gecko/20100101 Firefox/49.0";

有些资源是需要权限的,这个时候要伪装成某个用户,http协议是无状态的,标记信息都在cookie上面,给请求加上cookie

    request.Headers.Add("Cookie", "这里填cookie,从浏览器上面拷贝")

再完善下,设定个超时吧

   request.Timeout = 5000;

有些网站提供资源是GZIP压缩,这样可以节省带宽,所以请求头再加个

request.Headers.Add("Accept-Encoding", " gzip, deflate, br");

相应的得到相应流要有相对应的解压,这个时候httphelper变成这样了

           public static string DownLoadString(string url)            {                 string Source = string.Empty;                 try{                     HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
                request.UserAgent = "Mozilla/5.0 (Windows NT 10.0; WOW64; rv:49.0) Gecko/20100101 Firefox/49.0";

                request.Headers.Add("Cookie", "这里是Cookie");

                request.Headers.Add("Accept-Encoding", " gzip, deflate, br");
                request.KeepAlive = true;//启用长连接

                using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
                {

                    using (Stream dataStream = response.GetResponseStream())
                    {

                        if (response.ContentEncoding.ToLower().Contains("gzip"))//解压
                        {
                            using (GZipStream stream = new GZipStream(response.GetResponseStream(), CompressionMode.Decompress))
                            {
                                using (StreamReader reader = new StreamReader(stream, Encoding.UTF8))
                                {
                                    Source = reader.ReadToEnd();
                                }
                            }
                        }
                        else if (response.ContentEncoding.ToLower().Contains("deflate"))//解压
                        {
                            using (DeflateStream stream = new DeflateStream(response.GetResponseStream(), CompressionMode.Decompress))
                            {
                                using (StreamReader reader = new StreamReader(stream, Encoding.UTF8))
                                {
                                    Source = reader.ReadToEnd();
                                }

                            }
                        }
                        else
                        {
                            using (Stream stream = response.GetResponseStream())//原始
                            {
                                using (StreamReader reader = new StreamReader(stream, Encoding.UTF8))
                                {

                                    Source = reader.ReadToEnd();
                                }
                            }
                        }

                    }
                }
                request.Abort();
            }
            catch
            {
                Console.WriteLine("出错了,请求的URL为{0}", url);

            }
            return Source;}

请求态度会被服务器拒绝,返回429。这个时候需要设置代理,我们的请求会提交到代理服务器,代理服务器会向目标服务器请求,得到的响应由代理服务器返回给我们。只要不断切换代理,服务器不会因为请求太频繁而拒绝掉程序的请求
   var proxy = new WebProxy(“Adress”,8080);//后面是端口号
   request.Proxy = proxy;//为httpwebrequest设置代理

至于如何获取代理,请见后面的博客


 
时间: 2024-08-03 21:41:19

抓取百万知乎用户信息之HttpHelper的迭代之路的相关文章

PHP开发:使用PHP抓取百万知乎用户以及知识点札记

代码托管地址:https://github.com/hhqcontinue/zhihuSpider 开发前的准备 安装Linux系统(Ubuntu14.04),在VMWare虚拟机下安装一个Ubuntu: 安装PHP5.6或以上版本: 安装curl.pcntl扩展. 使用PHP的curl扩展抓取页面数据 PHP的curl扩展是PHP支持的允许你与各种服务器使用各种类型的协议进行连接和通信的库. 本程序是抓取知乎的用户数据,要能访问用户个人页面,需要用户登录后的才能访问.当我们在浏览器的页面中点击

抓取百万知乎用户数据之爬取思路

一.如何获取到用户的信息 前往用户主页,以轮子哥为例 从中可以看到用户的详细信息,教育经历主页,主修.所在行业,公司,关注量,回答数,居住地等等.打开开发者工具栏查看网络,即可找到,一般是html或者json这个数据在Html页面里. URL为https://www.zhihu.com/people/excited-vczh/answers,excited-vczh是轮子哥的id,我们只要拿到某个人的Id就可以获取详细信息了. 二.信息藏在哪 对这个json数据进行解析,即可找到用户信息 根据U

抓取百万知乎用户设计之实体设计

一.实体的关系 实体是根据返回的Json数据来设计的 教育经历方面 用户可以有很多教育经理,USER和education是一对多的关系,一个education对应一个education 一个用户可以有多个工作,当然很多人可以从事同一份工作,每份工作对应一家公司,对应一个岗位 每个用户可以有多个居住地,同一个居住地有多个用户,每个用户有一个行业,同一个行业有多个用户 代码实现就不列举了,创建一个Model类库项目 二.数据库上下文 public class ZhihuEntity : DbCont

Python爬虫从入门到放弃(十八)之 Scrapy爬取所有知乎用户信息(上)

爬取的思路 首先我们应该找到一个账号,这个账号被关注的人和关注的人都相对比较多的,就是下图中金字塔顶端的人,然后通过爬取这个账号的信息后,再爬取他关注的人和被关注的人的账号信息,然后爬取被关注人的账号信息和被关注信息的关注列表,爬取这些用户的信息,通过这种递归的方式从而爬取整个知乎的所有的账户信息.整个过程通过下面两个图表示: 爬虫分析过程 这里我们找的账号地址是:https://www.zhihu.com/people/excited-vczh/answers我们抓取的大V账号的主要信息是:

如何爬取了知乎用户信息,并做了简单的分析

爬虫:python27 +requests+json+bs4+time 分析工具: ELK套件 开发工具:pycharm 1.性别分布 0 绿色代表的是男性 ^ . ^ 1 代表的是女性 -1 性别不确定 可见知乎的用户男性颇多. 2.粉丝最多的top30 粉丝最多的前三十名:依次是张佳玮.李开复.黄继新等等,去知乎上查这些人,也差不多这个排名,说明爬取的数据具有一定的说服力. 3.写文章最多的top30 爬虫架构图如下: 说明: 选择一个活跃的用户(比如李开复)的url作为入口url.并将已爬

Python爬虫从入门到放弃(十九)之 Scrapy爬取所有知乎用户信息(下)

在上一篇文章中主要写了关于爬虫过程的分析,下面是代码的实现,完整代码在:https://github.com/pythonsite/spider items中的代码主要是我们要爬取的字段的定义 class UserItem(scrapy.Item): id = Field() name = Field() account_status = Field() allow_message= Field() answer_count = Field() articles_count = Field()

基于webmagic的爬虫小应用--爬取知乎用户信息

听到“爬虫”,是不是第一时间想到Python/php ? 多少想玩爬虫的Java学习者就因为语言不通而止步.Java是真的不能做爬虫吗? 当然不是. 只不过python的3行代码能解决的问题,而Java要30行. 这里推荐大家一个大牛做的java爬虫框架 [WebMagic] 文档简单易懂!java爬虫开发的福利啊! 一起来动手做一个小应用吧! 爬虫小应用–知乎用户信息 爬虫思想有3步 1. 抽取目标链接 2. 抽取需要的信息 3. 处理数据 一. 抽取目标链接 (确定入口地址,这里的入口是ht

scrapy 知乎用户信息爬虫

zhihu_spider 此项目的功能是爬取知乎用户信息以及人际拓扑关系,爬虫框架使用scrapy,数据存储使用mongo,下载这些数据感觉也没什么用,就当为大家学习scrapy提供一个例子吧.代码地址:https://github.com/LiuRoy/zhihu_spider,欢迎各位大神指出问题,另外知乎也欢迎大家关注哈 ^_^. 流程图 请求https://www.zhihu.com获取页面中的_xsrf数据,知乎开启了跨站请求伪造功能,所有的POST请求都必须带上此参数. 提交用户名,

如何有效抓取SQL Server的BLOCKING信息

原文:如何有效抓取SQL Server的BLOCKING信息 转自:微软亚太区数据库技术支持组 官方博客 http://blogs.msdn.com/b/apgcdsd/archive/2011/12/12/sql-server-blocking.aspx SQL Server允许并发操作,BLOCKING是指在某一操作没有完成之前,其他操作必须等待,以便于保证数据的完整性.BLOCKING的解决方法要查看BLOCKING的头是什么,为什么BLOCKING头上的语句执行的很慢.通常来讲只要我们能