临沂网站备案公司,网站做,网站制作 需要什么网络技术,伊春网站建设公司前言本文利用python的scrapy框架对虎牙web端的主播、主播订阅数、主播当前观看人数等基本数据进行抓取#xff0c;并将抓取到的数据以csv格数输出#xff0c;以及存储到mongodb中思路观察虎牙网站后确认所有频道url都在www.huya.com/g中的#xff0c;而主播房间数据则是ajax…前言本文利用python的scrapy框架对虎牙web端的主播、主播订阅数、主播当前观看人数等基本数据进行抓取并将抓取到的数据以csv格数输出以及存储到mongodb中思路观察虎牙网站后确认所有频道url都在www.huya.com/g中的而主播房间数据则是ajax异步数据获取数据的链接为http://www.huya.com/cache.php?mLiveListdogetLiveListByPagegameId{频道id}tagAll0page{页码}该链接通过控制gameId和page来返回某频道下某页的数据根据以上观察爬行设计思路如下第一步访问www.huya.com/g页面在li(class类型为game-list-item)中获取当前所有频道的链接、标题、频道id第二步根据第一步获取到的频道的链接进入频道页面在频道页面获取当前频道页数再根据该频道id页数构造异步数据请求链接第三步从第二步中获取频道返回的异步数据内容将返回的json数据类型转化为字典再获取要抓取的目标内容。第四步向第三步中获取到的主播房间url发出请求,进入房间页面后抓取主播订阅数第五步将数据输出为csv格式以及存在mongodb数据库中。频道分类页面ajax异步请求对应的链接代码items在items中定义要抓取的字段内容items代码如下class HuyaspiderItem(scrapy.Item):channel scrapy.Field() #主播所在频道anchor_category scrapy.Field() #主播类型anchor_name scrapy.Field() #主播名称anchor_url scrapy.Field() #直播房间链接anchor_tag scrapy.Field() #主播标签anchor_roomname scrapy.Field() #主播房间名称position scrapy.Field() #当前频道的主播排名watch_num scrapy.Field() #观看人数fan_num scrapy.Field() #订阅数量crawl_time scrapy.Field() #爬取时间pipelines在pipelines中设置输出为csv表以及将数据保存到mongodb中pipelines代码设置如下# -*- coding: utf-8 -*-import json,codecsimport pymongoclass HuyaspiderPipeline(object):def __init__(self):self.file codecs.open(huyaanchor.csv,wb,encodingutf-8) #创建以utf-8编码的csv文件client pymongo.MongoClient(localhost,27017) #创建mongodb连接db client[huya] #创建mongodb数据库huyaself.collection db[huyaanchor] #创建数据库huya中collectiondef process_item(self, item, spider):item dict(item) #将抓到的item转为dict格式line json.dumps(item)\n #定义line字段将抓到的item转为jump格式加上空格换行self.file.write(line.decode(unicode_escape)) #将line写进csv中输出self.collection.insert(item) #将item写进mongodb中middlewares在middlewares中以继承UserAgentMiddleware父类方式创建创建HuyaUserAgentMiddlewares类该类用于scrapy每次执行请求时使用指定的useragentmiddlewares代码如下from scrapy import signalsfrom scrapy.downloadermiddlewares.useragent import UserAgentMiddlewareimport randomclass HuyaUserAgentMiddleware(UserAgentMiddleware):def __init__ (self,user_agent):定义随机user_agent列表self.user_agent user_agentself.ua_list [Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; AcooBrowser; .NET CLR 1.1.4322; .NET CLR 2.0.50727),Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0; Acoo Browser; SLCC1; .NET CLR 2.0.50727; Media Center PC 5.0; .NET CLR 3.0.04506),Mozilla/4.0 (compatible; MSIE 7.0; AOL 9.5; AOLBuild 4337.35; Windows NT 5.1; .NET CLR 1.1.4322; .NET CLR 2.0.50727),Mozilla/5.0 (Windows; U; MSIE 9.0; Windows NT 9.0; en-US),Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Win64; x64; Trident/5.0; .NET CLR 3.5.30729; .NET CLR 3.0.30729; .NET CLR 2.0.50727; Media Center PC 6.0),Mozilla/5.0 (compatible; MSIE 8.0; Windows NT 6.0; Trident/4.0; WOW64; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; .NET CLR 1.0.3705; .NET CLR 1.1.4322),Mozilla/4.0 (compatible; MSIE 7.0b; Windows NT 5.2; .NET CLR 1.1.4322; .NET CLR 2.0.50727; InfoPath.2; .NET CLR 3.0.04506.30),Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN) AppleWebKit/523.15 (KHTML, like Gecko, Safari/419.3) Arora/0.3 (Change: 287 c9dfb30),Mozilla/5.0 (X11; U; Linux; en-US) AppleWebKit/527 (KHTML, like Gecko, Safari/419.3) Arora/0.6,Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.2pre) Gecko/20070215 K-Ninja/2.1.1,Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN; rv:1.9) Gecko/20080705 Firefox/3.0 Kapiko/3.0,]self.count0def process_request(self,request,spider):ua Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:53.0) Gecko/20100101 Firefox/53.0request.headers.setdefault(Use-Agent,ua) #设定reuqest使用的Use-Agent为uarequest.headers.setdefault(Host,www.huya.com) #设定reuqest使用的Host为www.huya.comrequest.headers.setdefault(Referer,http://www.huya.com/) #设定reuqest使用的Referer为http://www.huya.com/settingssettings配置如下,在“DOWNLOADER_MIDDLEWARES”以及“ITEM_PIPELINES”设置上述items和middlewares中的配置。DOWNLOADER_MIDDLEWARES {huyaspider.middlewares.HuyaUserAgentMiddleware: 400, #启动middlewares中设定好的usragentscrapy.contrib.downloadermiddleware.useragent.UserAgentMiddleware:None, #禁用默认的usragent}ITEM_PIPELINES {huyaspider.pipelines.HuyaspiderPipeline: 300, #设置pipelines}spider在spider中定义了parse、channel_get、channel_parse、room_parse四个函数其作用说明如下parse 获取虎牙下所有频道的url 、频道id 、频道名称channel_get def parse的回调函数根据频道id构造主播数据连接并执行请求channel_parse channel_get 的回调函数根据返回的json数据抓取相应内容并抓出主播的房间链接对房间链接执行请求room_parse channel_parse的回调函数抓取主播的订阅数量代码如下# -*- coding: utf-8 -*-import scrapy,re,json,timefrom scrapy.http import Requestfrom huyaspider.items import HuyaspiderItemclass HuyaSpider(scrapy.Spider):name huyaallowed_domains [www.huya.com] #设置爬虫允许抓取的start_urls [http://www.huya.com/g] #设置第一个爬取的urlallow_pagenum 5 #设置爬取频道的数量total_pagenum 0 #计算档前已爬取频道的数量url_dict{} #设置存放url的dictdef parse(self,response):parse_content response.xpath(/html/body/div[3]/div/div/div[2]/ul/li) #抓取当前频道for i in parse_content:channel_title i.xpath(a/p/text()).extract() #抓取频道名称channel_url i.xpath(a/href).extract_first() #抓取当前频道urlchannel_id i.xpath(a/report).re(rgame_id\D*(.*)\D\}) #抓取当前频道对应的id用正则去掉不需要部分channel_data {url:channel_url,channel_id:channel_id[0]} #将频道url和频道id组成一一对应的dictself.url_dict[channel_title[0]]channel_data #将频道名称和channel_data添加在url_dict中if self.total_pagenum self.allow_pagenum: #用于控制爬出抓取数量当total_pagenum小于allow_pagenum 继续爬self.total_pagenum 1yield Request(urlchannel_url,meta{channel_data:channel_data,channel:channel_title},callbackself.channel_get) #使用requestmeta携带数据为频道url频道id回调函数为channel_getdef channel_get(self, response):page_num int( response.xpath(/html/body/div[3]/div/div/div[js-list-page]/div[1]/data-pages).extract_first( ) ) #抓取当前频道一共有多少页并转为int格式channel_id response.meta[channel_data][channel_id] #将传入meta的dict(channel_data)中的channel_id值赋给channel_id该id用于构造url从而实现翻页channel response.meta[channel] #将传入的meta的dict中的channel_id值赋给channel_idfor i in range(1,page_num1): #根据page_num数量构造下一页并继续抓取url http://www.huya.com/cache.php?mLiveListdogetLiveListByPagegameId{gameid}tagAll0page{page}.format(gameidchannel_id,pagei) #获取下一页的json数据yield Request(urlurl,meta{page:i,channel:channel},callbackself.channel_parse) #meta携带数据为频道当前页码频道名称回调函数为channel_parsedef channel_parse(self, response):print channel_parse startcount 0 #用于当前房间的位置计算位置response_json json.loads(response.text) #利用json.loads将json数据转为字典channel response.meta[channel]for i in response_json[data][datas]:count 1itemsHuyaspiderItem() #实例化item.HuyaspiderItemitems[channel] channel #获取频道名称items[anchor_category] i[gameFullName].replace(/n,) #获取主播类型并删内容中的换行符items[watch_num] i[totalCount] #获取观看数量items[anchor_roomname] i[roomName] #获取房间名称items[anchor_url] http://www.huya.com/i[privateHost] #获房间urlitems[anchor_name] i[nick] #获主播名称items[anchor_tag] i[recommendTagName] #获主播推荐标签items[position] str(response.meta[page])-str(count) #获取所在频道的位置yield Request(urlitems[anchor_url],meta{items:items},callbackself.room_parse) #进入主播房间url获取主播订阅数量meta携带数据为刚抓取的items回调函数为room_parsedef room_parse(self,response):print room_parse startitems response.meta[items]try:items[fan_num] response.xpath(/html/body/div[2]/div/div/div[1]/div[1]/div[2]/div/div[1]/div[2]/text()).extract() #获取主播订阅数量except Exception as e:items[fan_num] none #如果主播订阅数量为空值则数据则为noneitems[crawl_time] time.strftime(%Y-%m-%d %X,time.localtime()) #记录爬取时间yield items #输出items