本节讲解如何抓取豆瓣电影分类排行榜中的电影数据(https:movie。douban。comchart),比如输入犯罪则会输出所有犯罪影片的电影名称、评分,效果如下所示:剧情喜剧动作爱情科幻动画悬疑惊悚恐怖纪录片短片情色同性音乐歌舞家庭儿童传记历史战争犯罪西部奇幻冒险灾难武侠古装运动黑色电影你想了解什么类型电影:犯罪{name:肖申克的救赎,score:9。7}{name:控方证人,score:9。6}。。。电影总数量:302部123456复制代码类型:〔python〕确定网站类型 首先要明确豆瓣电影网站的类型,即是动态还是静态。检查方法:右键查看网页源码搜索辛德勒的名单关键字,如下图所示: 最终发现源码页中没有出现想要抓取的数据,只有一大堆的JS代码,由此确定该网站为动态网站。影片详情信息 接下来,使用快捷键F12打开控制台进行抓包,点击NetWork选项卡XHR选项Preview选项卡刷新当前页面抓取数据包,如下图所示: 从图2可知,我们想要抓取的数据取全部包含在当前的数据包中。当我们向下滚动鼠标滑轮时,左侧栏内的数据包会实现自动加载,这是使用Ajax异步加载技术实现的。 通过查看数据Headers选项可以明确url地址、查询参数等信息,如下所示: 从上图可以得知请求的基准URL(由于还未拼接查询参数,所以称之为基准URL),如下所示:https:movie。douban。comjcharttoplist?1复制代码类型:〔python〕 继续滚动鼠标滑轮可知查询参数具有如下规律:type:4电影类型intervalid:100:90代表网页上滑动条的百分比(好于10090的历史片)action:空start:0每次加载电影的起始索引值0204060limit:20每次加载的电影数量,1为初始值,后续加载时20固定不变12345复制代码类型:〔python〕 注意:寻找规律时,后加载出来的数据包会排在最前面,除去第一个数据包外,其余数据包如下所示:影片总数量 注意:第一个数据包反映了每个类型中电影的总数量,其url与响应信息如下:请求的URL地址:https:movie。douban。comjcharttoplistcount?type4intervalid1003A90Response信息:{playablecount:41,total:104,unwatchedcount:104}12复制代码类型:〔java〕影片类型与类型码 影片的类型与类型码包含在电影排行榜的主界面中,如下所示: 分析上述页面结构,然后使用正则表达式来提取想要的数据,并定义选择菜单menu,代码如下所示:importredefgetalltypefilms(self):获取影片类型和类型码urlhttps:movie。douban。comchartheadersself。getheaders()htmlrequests。get(urlurl,headersheaders)。textrebdsrpatternre。compile(rebds,re。S)rlistpattern。findall(html)存放所有类型和对应类型码大字典typedict{}定义一个选择电影类型的菜单menurlist〔{剧情,11},{},。。〕forrinrlist:typedict〔r〔0〕。strip()〕r〔1〕。strip()获取input的菜单,显示所有电影类型menur〔0〕。strip()返回类型字典以供后续函数调用,并返回输入菜单menu{剧情:11,喜剧:24,。。。}returntypedict,menu12345678910111213141516171819202122复制代码类型:〔python〕编写完整程序 完成上述分析后,下面开始编写Python爬虫程序,代码如下:coding:utf8importrequestsimporttimeimportrandomimportreimportjsonfromuainfoimportualistclassDoubanSpider(object):definit(self):self。urlhttps:movie。douban。comjcharttoplist?self。i0获取随机headersdefgetheaders(self):headers{UserAgent:random。choice(ualist)}returnheaders获取页面defgetpage(self,params):将json转换为python数据类型,并返回htmlrequests。get(urlself。url,paramsparams,headersself。getheaders())。texthtmljson。loads(html)self。parsepage(html)解析并保存数据defparsepage(self,html):item{}html列表类型:〔{电影1},{电影2},{电影3}。。。〕foroneinhtml:名称评分item〔name〕one〔title〕。strip()item〔score〕float(one〔score〕。strip())print(item)self。i1获取电影总数deftotalnumber(self,typenumber):F12抓包抓到的地址,type表示电影类型urlhttps:movie。douban。comjcharttoplistcount?type{}intervalid1003A90。format(typenumber)headersself。getheaders()htmlrequests。get(urlurl,headersheaders)。json()totalint(html〔total〕)returntotal获取所有电影的类型和对应type值defgetalltypefilms(self):获取类型与类型码urlhttps:movie。douban。comchartheadersself。getheaders()htmlrequests。get(urlurl,headersheaders)。textrebdsrpatternre。compile(rebds,re。S)rlistpattern。findall(html)存放所有类型和对应类型码大字典typedict{}定义一个选择电影类型的菜单menuforrinrlist:typedict〔r〔0〕。strip()〕r〔1〕。strip()获取input的菜单,显示所有电影类型menur〔0〕。strip()returntypedict,menu主程序入口函数defmain(self):获取type的值typedict,menuself。getalltypefilms()menumenu你想了解什么类型电影:nameinput(menu)typenumbertypedict〔name〕获取电影总数totalself。totalnumber(typenumber)forstartinrange(0,(total1),20):构建查询参数params{type:typenumber,intervalid:100:90,action:,start:str(start),limit:20}调用函数,传递params参数self。getpage(params)随机休眠13秒time。sleep(random。randint(1,3))print(电影总数量:d部self。i)ifnamemain:spiderDoubanSpider()spider。main()1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283复制代码类型:〔python〕 输出示例:剧情喜剧动作爱情科幻动画悬疑惊悚恐怖纪录片短片情色同性音乐歌舞家庭儿童传记历史战争犯罪西部奇幻冒险灾难武侠古装运动黑色电影你想了解什么类型电影:科幻{name:盗梦空间,score:9。3}{name:星际穿越,score:9。3}{name:楚门的世界,score:9。3}{name:机器人总动员,score:9。3}{name:蝙蝠侠:黑暗骑士,score:9。2}{name:超感猎杀:完结特别篇,score:9。2}{name:新世纪福音战士第0:0话诞生之始,score:9。2}{name:少年骇客:变身之谜,score:9。2}。。。。。。电影总数量:147部12345678910111213复制代码类型:〔python〕 最后我们对抓取动态网站数据做简单地总结: 1。确定网站是否为动态网站,通过查看源码搜索相应的关键字即可确定。 2。动态网站主要通过异步方式加载数据。触发数据加载的JS事件主要有滚动鼠标滑轮、鼠标点击、拉动滚动条等有关动作,也有一些网站通过局部更新的方式加载数据,比如有道翻译案例。 新闻资讯开课吧广场第1页