Python动态网页爬取

       前面所讲的都是对静态网页进行抓取,本博客介绍动态网站的抓取。 动态网站的抓取 相比静态网页来说困难一些,主要涉及的技术是Ajax和动态Html。简单的网页访问是无法获取完整的数据,需要对数据加载流程进行分析。针对不同的动态网页爬取方法,将分别用具体实例进行介绍。本博客主要是直接利用Ajax来获取数据。

 

页面分析

本博客以MTime电影网为例,主要爬取电影的评分票房等信息。首先使用火狐浏览器的控制台来查看页面信息。

对于页面中的票房信息是无法在HTML中获取到,其是通过js进行动态加载获得的,那么就查找相应的js响应。就是从一堆js请求中查看一些含有Ajax字段的请求。http://service.library.mtime.com/Movie.api?Ajax_CallBack=true&Ajax_CallBackType=Mtime.Library.Services&Ajax_CallBackMethod=GetMovieOverviewRating&Ajax_CrossDomain=1&Ajax_RequestUrl=http%3A%2F%2Fmovie.mtime.com%2F242129%2F&t=2020512134567406&Ajax_CallBackArgument0=242129

点进去之后查看返回的数据:

找到相应的链接和返回数据之后,就需要分析这个链接的构造方法和分析返回的数据。

(1)在链接中一共有7个参数,我们首先需要分析那些参数是不变的哪些是更具不同电影变化的。通过对比两个不同的电影链接可以发现其中有4个参数不变,有3个参数是动态变化的,分别是Ajax_RequestRrl、t和Ajax_CallBackArgument0。通过分析可以发现这三个参数分别表示的是当前页面url、当前请求时间和电影表示的数字。

(2)提取响应数据。响应内容主要分为三种,分别是正在上映的电影信息,一种即将上映的电影信息,最后一种是还有比较长时间才能上映的电影信息。具体的在代码中展示。

 

具体实现代码

本文代码是基于博客实现的,本博客只是将其中需要更改的部分修改了。

网页解析

在HtmlParser类中定义一个parser_url方法,代码如下:

 def parser_url(self, page_url, response):
        pattern = re.compile(r'(http://movie.mtime.com/(\d+)/)')
        urls = pattern.findall(response)
        if urls != None:
            return list(set(urls))
        else:
            return None

提取响应数据中的有效数据:

 def parser_json(self, page_url, respone):
        """
        解析响应
        :param page_url:
        :param respone:
        :return:
        """
        #将“=”和“;”之间的内容提取出来
        pattern = re.compile(r'=(.*?);')
        result = pattern.findall(respone)[0]

        if result != None:
            value = json.loads(result)
            try:
                isRelease = value.get('value').get('isRelease')
            except Exception,e:
                print(e)
                return None
            if isRelease:
                if value.get('value').get('hotValue') == None:
                    return self._parser_release(page_url, value)
                else:
                    self._parser_no_release(page_url, value, isRelease = 2)
            else:
                return self._parser_no_release(page_url, value)


    def _parser_release(self, page_url, value):
        """
        解析已上映的影片
        :param page_url:
        :param value:
        :return:
        """
        try:
            isRelease = 1
            movieRating = value.get('value').get('movieRating')
            boxOffice = value.get('value').get('boxOffice')
            movieTitle = value.get('value').get('movieTitle')
            RPictureFinal = movieRating.get('RPictureFinal')
            RStoryFinal = movieRating.get('RStoryFinal')
            RDirectorFinal = movieRating.get('RDirectorFinal')
            ROtherFinal = movieRating.get('ROtherFinal')
            RatingFinal = movieRating.get('RatingFinal')

            MovieId = movieRating.get('MovieId')
            Usercount = movieRating.get('Usercount')
            AttitudeCount = movieRating.get('AttitudeCount')

            TotalBoxOffice = boxOffice.get('TotalBoxOffice')
            TotalBoxOfficeUnit = boxOffice.get('TotalBoxOfficeUnit')
            TodayBoxOffice = boxOffice.get('TodayBoxOffice')
            TodayBoxOfficeUnit = boxOffice.get('TodayBoxOfficeUnit')

            showDays = boxOffice.get('ShowDays')

            try:
                Rank = boxOffice.get('Rank')
            except Exception,e:
                Rank = 0
            return (MovieId,movieTitle,RatingFinal,
                    ROtherFinal,RPictureFinal,RDirectorFinal,
                    RStoryFinal,Usercount,AttitudeCount,
                    TotalBoxOffice+TotalBoxOfficeUnit,
                    TodayBoxOffice+TodayBoxOfficeUnit,
                    Rank,showDays,isRelease)
        except Exception,e:
            print(e,page_url,value)
            return None


    def _parser_no_release(self,page_url,value,isRelease = 0):

        try:
            movieRating = value.get('value').get('movieRating')
            movieTitle = value.get('value').get('movieTitle')

            RPictureFinal = movieRating.get('RPictureFinal')
            RStoryFinal = movieRating.get('RStoryFinal')
            RDirectorFinal = movieRating.get('RDirectorFinal')
            ROtherFinal = movieRating.get('ROtherFinal')
            RatingFinal = movieRating.get('RatingFinal')

            MovieId = movieRating.get('MovieId')
            Usercount = movieRating.get('Usercount')
            AttitudeCount = movieRating.get('AttitudeCount')

            try:
                Rank = value.get('value').get('hotValue').get('Ranking')
            except Exception,e:
                Rank = 0
            return (MovieId,movieTitle,RatingFinal,
                    ROtherFinal,RPictureFinal,RDirectorFinal,
                    RStoryFinal,Usercount,AttitudeCount,u'无',
                    u'无',Rank,0,isRelease)
        except Exception,e:
            print(e, page_url, value)
            return None

爬虫调度器

    def dynamic_crawl(self, root_url):
        content = self.downloader.download(root_url)
        urls = self.parser.parser_url(root_url,content)
        for url in urls:
            try:
                t = time.strftime("%Y%m%d%H%M%S3282", time.localtime())
                rank_url ='http://service.library.mtime.com/Movie.api'\
                    '?Ajax_CallBack=true'\
                    '&Ajax_CallBackType=Mtime.Library.Services'\
                    '&Ajax_CallBackMethod=GetMovieOverviewRating'\
                    '&Ajax_CrossDomain=1'\
                    '&Ajax_RequestRrl=%s'\
                    '&t=%s'\
                    '&Ajax_CallBackArgument0=%s'%(url[0],t,url[1])
                rank_content = self.downloader.download(rank_url)
                data = self.parser.parser_json(rank_url,rank_content)
                print(data)
            except Exception,e:
                print('Crawl failed')

if __name__=="__main__":
    spider_main = SpiderMain()
    spider_main.dynamic_crawl("http://theater.mtime.com/China_Beijing/")

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值