python - urllib获取到的内容转为 BeautifulSoup bs4对象后内容发生变化

 心语忆录_288 发布于 2022-11-03 13:31

http://samsung-updates.com/device/?id=SM-N9007
这个网址用linux curl和直接用urllib获取到的内容都是正常的,主要关注 table id="flist" 节点的内容如下:

但如果将获取到的内容转成bs4对象,获取的内容就不对了。请参见以下代码:

import urllib.request
from bs4 import BeautifulSoup

def get_dom(page_url,encoding):
    opener = urllib.request.build_opener()
    opener.addheaders = [('User-agent', 'Mozilla/5.0 (X11; U; Linux i686) Gecko/20071127 Firefox/2.0.0.11')]
    dom = opener.open(page_url)
    return dom.read().decode(encoding)
    dom.close()

def get_post_content(post_url):
    soup_post = BeautifulSoup(get_dom(post_url,"utf-8"))
    print(soup_post)

get_post_content("http://samsung-updates.com/device/?id=SM-N9007")

print出来的内容变成了:



Device Name
Model
Region
Version
OS
OS Version
Build Date
Changelist
Unlock
Galaxy Note 3 (Snapdragon/SM-N9007) SM-N9007 TGYHong kong N9007ZHU3ANG2 Android 4.4.2 10.07.2014 2188588 Unlock Download File
Device Name
Model
Region
Version
OS
OS Version
Build Date
Changelist
Unlock

Galaxy Note 3 (Snapdragon/SM-N9007) SM-N9007 TGYHong kong N9007ZHU3ANG2 Android 4.4.2 10.07.2014 2188588 Unlock Download File

请注意第一个tr节点后,table闭合了,还有有很多p闭合的标记。

这个问题导致我没法正确抓取表格的内容,求教下是不是我哪里有问题?

2 个回答
  • 入过这个坑!

    就是解释器的问题。虽然bs官方推荐lxml解释器,但是它的最大缺点是,如果你的html源码本身有问题,比如一个

    没写对应,它会直接把它删掉,然后返给你。
    所以用html5lib绝对没问题。
    pip install html5lib安装,然后实例化改成soup = BeautifulSoup(html, 'html5lib')就好了。
    另外,bs4后,BeautifulSoup(html, 'html5lib')这种双参数,是必须的,否则肯定出问题。
    2022-11-12 01:41 回答
  • 这是因为BeautifulSoup默认使用的HTML解析器(即标准库里的那个)对你的页面解析出错。解决方法是换一个解析器。

    参见http://www.crummy.com/software/BeautifulSoup/bs4/doc/index.zh.html

    P.S. 我用Python3.4,装了html5lib,并且在代码里用BeautifulSoup(xxx, 'html5lib')可以正确获得你想要的东西。

    再P.S. 现在比较流行的html解析库是PyQuery,因为它的语法跟jQuery很像,很容易上手。而http库一般用requests,也是因为它提供的api很简单

    import requests
    from pyquery import PyQuery as pq
    
    def html(url):
        return requests.get(url).text
    
    
    def table(text):
        return pq(text)('table#flist')
    
    
    def table_from_url(url):
        return pq(url=url)('table#flist')
    
    
    if __name__ == '__main__':
        print(table(html('http://samsung-updates.com/device/?id=SM-N9007')))
        # or
        print(table_from_url('http://samsung-updates.com/device/?id=SM-N9007'))
    
    2022-11-12 01:41 回答
撰写答案
今天,你开发时遇到什么问题呢?
立即提问
热门标签
PHP1.CN | 中国最专业的PHP中文社区 | PNG素材下载 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有