• 关于Python json解析过程遇到的TypeError: expected string or buffer


    关于Python json解析过程遇到的问题:(爬取天气json数据所遇到的问题http://tianqi.2345.com/)

    part.1

    url——http://tianqi.2345.com/t/wea_history/js/201708/60061_201708.js

    返回的数据如下:

    这就尴尬了,直接json.loads是返回错误的。

    对比了其他网页返回的——http://www.toutiao.com/search_content/?offset=0&format=json&keyword=%E8%A1%97%E6%8B%8D&autoload=true&count=20&cur_tab=1

    是不是格式问题:多了var……

    于是乎谷歌解决办法:

    1、将所有‘变成” 2、添加“”(因为字典的键格式不标准,比如ymd没有双引号的)3、json前处理好数据 比如截断var weather_str={city:'新河',tqInfo:这部分

    url = 'http://tianqi.2345.com/t/wea_history/js/201708/60061_201708.js'
    r = requests.get(url).text
    s=r.split("tqInfo:")[1]
    s=s.split(",maxWendu")[0]
    s=s.replace("'",'"')
    
    s =re.sub(r'[a-zA-Z]+',lambda x:'"'+x.group(0)+'"',s)
    print s
    
    data = json.loads(s)
    for i in data:
        print i['aqi']

    ok,经过数据清洗处理,勉强能用。

    但是好奇怪,为什么返回的json数据是这样的?比较大型的网页也这样马虎?难道是为了反爬虫的设置?  带着这些问题,我们进入下一个环节

    --------------------------------------------------

    part.2——selenium+phantomjs模拟爬取

    from selenium import webdriver
    driver = webdriver.PhantomJS()
    #executable_path为你的phantomjs可执行文件路径
    driver.get("http://tianqi.2345.com/wea_history/60061.htm")
    
    #或得js变量的值
    r = driver.execute_script("return weather_str")
    print r

    得到的结果:

    注意:

    返回的结果跟用requests返回的不一致,少了var weather_str…… 免除数据清洗的烦恼。

    回到part1最后的疑问,也就是说不是网页设计问题,其实是自己境界未到,还不知道这样的处理方法。原来是这样处理的,自己还是太肤浅了。

     推测:应该有反爬虫设置,返回json数据经过浏览器加载能正确呈现数据,直接requests得到数据不规整,限制获取

    很接近了,但是用json.loads还是返回错误TypeError: expected string or  buffer

    奇怪了  奇怪了  奇怪了,为什么这样?返回类型很标准了啊,正常可以解析啦

     
     

    解决办法:——谷歌+try尝试输出。

    for i in data:
        print i

    这玩意直接就是字典啊,输出的都是字典键,然后详细信息都在tqInfo里面啊。

    经过这样处理,爬取的信息可以拿出来并且使用了,但是为什么不用json呢?明明返回的是json数据啊

    -------------------------------------------------------------

    part.3——TypeError: expected string or buffer  ——使用dumps和loads解决

    百思不得其解。经过调试,最终发现,python中默认使用单引号表示字符串"'"
    所以当,用字符串符值以后,python会把双引号转换为单引号,但是json不支持单引号。
    也就是说:
    先dumps转换,再loads转换,最终得出我们想要的结果,一步到位。
    from selenium import webdriver
    driver = webdriver.PhantomJS()
    #executable_path为你的phantomjs可执行文件路径
    driver.get("http://tianqi.2345.com/wea_history/60061.htm")
    
    #或得js变量的值
    r = driver.execute_script("return weather_str")
    
    
    json_str = json.dumps(r)
    
    python_obj = json.loads(json_str)
    print python_obj
    for i in python_obj:
        print i

    一波三折,终于把这个问题解决了。

  • 相关阅读:
    js 字符串转化成数字
    web项目中各种路径的获取
    个人作业——软件工程实践总结作业
    Beta 答辩总结
    Beta 冲刺 (7/7)
    Beta 冲刺 (6/7)
    Beta 冲刺 (5/7)
    Beta 冲刺 (4/7)
    Beta 冲刺 (3/7)
    软件产品案例分析(团队)
  • 原文地址:https://www.cnblogs.com/vhills/p/7404443.html
Copyright © 2020-2023  润新知