• [Python] 豆瓣电影top250爬虫


    1.分析

    <li><div class="item">电影信息</div></li>

    每个电影信息都是同样的格式,毕竟在服务器端是用循环生成的html,这样解析出电影的信息就很简单了

    豆瓣电影top250的翻页也很简单,直接就在url上修改一个start就行了,start代表这一页从start+1开始

    比如 https://movie.douban.com/top250?start=0&filter=, 就是top1到top25,每页25部电影,翻页把start+=25就行了,一直加到225

    2.获取网页的html

    使用python内置的urllib库

    不过得到的网页中并没有中文,而是会出现这样的字符串

    xe8xaexa9xe5xa5xbdxe7x94xb5xe5xbdxb1xe6x9dxa5xe6x89xbexe4xbdxa0

    这是中文的utf-8编码的16进制版本

    先将x去除,变成

    e8aea9e5a5bde794b5e5bdb1e69da5e689bee4bda0

    然后每6位是一个中文字符

    E8 AE A9 让

    E5 A5 BD 好

    E7 94 B5 电

    。。。

    全文是【让好电影来找你】

    可以在这个网站上输入16进制的UTF-8编码来查找对应字符

    def GetHtml(url):
        print('Url : '+url)
        f = request.urlopen(url.format(start))
        data = f.read()
        htmls.append(data.decode('utf-8'))

    3.解析网页

    简单提下XPath的语法

    nodename 选取此节点的所有子节点。
    / 从根节点选取。
    // 从匹配选择的当前节点选择文档中的节点,而不考虑它们的位置。
    . 选取当前节点。
    .. 选取当前节点的父节点。
    @ 选取属性。

    先解析出<div class="item">,再对这个div中的内容进行第二次解析

     这里值得注意的是打印一个element内的html要用etree.tostring()

    tree = etree.HTML(str)
    result = tree.xpath('//div[@class="item"]')  //获取所有<div class="item">元素
    print(etree.tostring(result[0], encoding='unicode')) //随便打印一个

    打印出来的就是这样的

    <div class="item">
                    <div class="pic">
                        <em class="">1</em>
                        <a href="https://movie.douban.com/subject/1292052/">
                            <img width="100" alt="肖申克的救赎" src="https://img3.doubanio.com/view/photo/s_ratio_poster/public/p480747492.jpg" class=""/>
                        </a>
                    </div>
                    <div class="info">
                        <div class="hd">
                            <a href="https://movie.douban.com/subject/1292052/" class="">
                                <span class="title">肖申克的救赎</span>
                                        <span class="title"> / The Shawshank Redemption</span>
                                    <span class="other"> / 月黑高飞(港)  /  刺激1995(台)</span>
                            </a>
    
    
                                <span class="playable">[可播放]</span>
                        </div>
                        <div class="bd">
                            <p class="">
                                导演: 弗兰克·德拉邦特 Frank Darabont   主演: 蒂姆·罗宾斯 Tim Robbins /...<br/>
                                1994 / 美国 / 犯罪 剧情
                            </p>
    
    
                            <div class="star">
                                    <span class="rating5-t"/>
                                    <span class="rating_num" property="v:average">9.6</span>
                                    <span property="v:best" content="10.0"/>
                                    <span>996499人评价</span>
                            </div>
    
                                <p class="quote">
                                    <span class="inq">希望让人自由。</span>
                                </p>
                        </div>
                    </div>
                </div>

    以上<div class="item">已经拿到了,开始进行第二次解析(可以先用个list把这些div存起来,然后再弄个线程做第二次的解析,那是以后的事了,这里先不管)

     记录下这里踩的坑

    print(result[0].xpath('//img/@src')) //会返回整个页面的img的src

    这个奇怪的问题简直了,我甚至觉得是这个包的bug,我从result[0]那么一小段html用xpath查东西居然能查到整个html的,让我觉得我虽然是用result[0]调用的xpath,但内部没准根本不care谁调用的,一律使用最开始etree.HTML() 的到的这个对象调用xpath

    我的解决办法是改下xpath,指定从div开始找,或者是用 “."表示从当前节点开始找

    print(result[0].xpath('div//img/@src'))
    print(result[0].xpath('.//img/@src'))

    下面这段代码中的XPath可能不够简洁,但It's just works,毕竟这是第一个版本,随着我对python的熟练,还会继续改动

    主要是将一个p标签下的字符串连接起来并去除空格,转换各种特殊字符

    需要注意的是XPath返回的基本都是list类型的,很多博客里都直接调方法都没加下标取值,天知道是不是版本不一样

    def ProcessHtml(html):
        tree = etree.HTML(html)
        items = tree.xpath('//div[@class="item"]')
        
        for item in items:
            index = item.xpath('div//em/text()')[0]
            src = item.xpath('div//img/@src')[0]
            info = item.xpath('.//div[@class="bd"]/p')[0].xpath('string(.)').strip().replace(' ','').replace('xa0',' ').replace('
    ',' ')
            title = item.xpath('.//div[@class="hd"]/a')[0].xpath('string(.)').strip().replace(' ','').replace('xa0',' ').replace('
    ',' ')
            star = item.xpath('.//span[@class="rating_num"]/text()')[0]
            print ('''%s 
            %s 
            %s
            %s
            %s
            ''' %  (index,title,info,star,src))

    完整代码https://github.com/arcsinw/project_douban

    参考链接

    scrapy xpath 从response中获取li,然后再获取li中img的src

    XPath语法

    解决:xpath取出指定多标签内所有文字text

  • 相关阅读:
    Http与WWW服务精解
    Http与WWW服务精解
    6-13
    好用的工具说明
    JVM、JRE和JDK三者间的区别和联系
    css进阶之二:flex弹性布局
    MVVM
    如何理解TCP的三次握手协议?
    java里面的设计模式
    linux常用命令
  • 原文地址:https://www.cnblogs.com/arcsinw/p/8623012.html
Copyright © 2020-2023  润新知