V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
SuperMaskv
V2EX  ›  Python

Python 抓取豆瓣读书书籍详细内容遇到的字符串处理问题

  •  
  •   SuperMaskv · 2019-03-17 13:15:15 +08:00 · 1501 次点击
    这是一个创建于 2114 天前的主题,其中的信息可能已经有所发展或是发生改变。

    遇到的困难

    ​ 想要将下面的内容按照{'作者':'[美]卡勒德·胡赛尼','出版社':'上海人民出版社'}这样的格式保存在 dict 中。但是有效信息的位置太多样了,作为 Python 的初学者,刚刚接触美丽的汤,处理起来还不是很得心应手,希望有大佬帮忙解决一下。

    <div id="info" class="">
    
        <span class="pl">作者:</span>&nbsp;
            <a href="https://book.douban.com/author/997810/">
                    [美]
                卡勒德·胡赛尼</a>
        <br>
    
        <span class="pl">出版社:</span> 上海人民出版社<br>
    
        <span class="pl">出品方:</span>&nbsp;<a href="https://book.douban.com/series/39071?brand=1">世纪文景</a><br>
    
        <span class="pl">原作名:</span> The Kite Runner<br>
    
        <span class="pl">译者:</span>&nbsp;
            <a href="https://book.douban.com/author/4528877/">
                李继宏</a>
        <br>
    
        <span class="pl">出版年:</span> 2006-5<br>
    
        <span class="pl">页数:</span> 362<br>
    
        <span class="pl">定价:</span> 29.00 元<br>
    
        <span class="pl">装帧:</span> 平装<br>
    
        <span class="pl">丛书:</span>&nbsp;<a href="https://book.douban.com/series/19760">卡勒德·胡赛尼作品</a><br>
    
          <span class="pl">ISBN:</span> 9787208061644<br>
    
    </div>
    

    尝试过的方法

    把抓到的整个 div 变成字符串,然后对字符串做格式化处理。但是有类似原作名等字段让处理空格变成了难题。

    def getBookInfos(urlList):
        L = []
        for url in urlList:
    
            try:
                html = urlopen(url[0])
            except HTTPError as e:
                print(e)
                print(url[0])
                print(url[1])
    
            bsObj = BeautifulSoup(html, 'lxml')
            tagObjs = bsObj.findAll('div', {'id': 'info'})
            # 其实这个循环里只有一个 tag 参与
            for tag in tagObjs:
                dict = {}
                tag = str(tag)
                tag = tag.replace('<br/>', '*')
                reg = re.compile('<[^>]*>')
                content = reg.sub('', tag).replace('\n', '').replace(' ', '').replace('\xa0', '')
                infoList = content.split('*')
                infoList.pop()
                for info in infoList:
                    info = info.split(':')
                    dict[info[0]] = info[1]
            L.append(dict)
        return L
    

    希望能有大佬提供下解决思路,谢谢谢谢

    7 条回复    2019-03-21 18:36:52 +08:00
    SuperMaskv
        1
    SuperMaskv  
    OP
       2019-03-19 11:28:08 +08:00
    ...这么难受吗都没人理我
    adrianyoung
        2
    adrianyoung  
       2019-03-19 19:43:22 +08:00
    额,xpath(string(.))试一下不,印象中可以的把
    ml1344677
        3
    ml1344677  
       2019-03-20 16:25:34 +08:00
    hello 你的问题描述我大致清楚。我提供的思路是,find_all() id=info 下的所有 span 然后根据 class p1 拿到字段名 接着获取该 span 下除了字段名外所有字符即为 该字段的值。另外,这个页面的数据是比较格式化的 不建议使用正则来处理。
    ml1344677
        4
    ml1344677  
       2019-03-20 16:29:58 +08:00
    sorry 补充一点就是 span 下的意思是 下一个 span 之前的所有标签。
    SuperMaskv
        5
    SuperMaskv  
    OP
       2019-03-20 21:59:34 +08:00
    @adrianyoung xpath 还没有接触到,我到时候研究研究,谢谢
    SuperMaskv
        6
    SuperMaskv  
    OP
       2019-03-20 22:01:45 +08:00
    @ml1344677 我明白你的意思,之前也有试过你提供的方法,但是那个 ‘译者’ 处理起来还是很麻烦。还是谢谢你的详细回答。可能是我掌握的工具太少了,我再研究研究
    yxlbeyond
        7
    yxlbeyond  
       2019-03-21 18:36:52 +08:00
    建议是 xpath 和 regx 配合着使用,确保每一个 key 对应的 value 都是正确的
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2512 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 24ms · UTC 05:26 · PVG 13:26 · LAX 21:26 · JFK 00:26
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.