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
LeIYc
V2EX  ›  Python

爬天气数据,解析网页的时候有个元素不知道怎么取

  •  
  •   LeIYc · 2018-04-09 10:40:22 +08:00 · 4354 次点击
    这是一个创建于 2427 天前的主题,其中的信息可能已经有所发展或是发生改变。
    <div class="minMax">
    <div id="maxTempDiv" style="float: left;"><img src="http://i.tq121.com.cn/i/weather2017/max.png"><span id="maxTemp">26℃</span></div>
    <div id="minTempDiv" style="float: left;"><img src="http://i.tq121.com.cn/i/weather2017/min.png"><span id="minTemp">19℃</span></div>
    </div>


    怎么才能把温度信息 取出来。
    temp_list = soup.find_all('span',id='maxTemp')
    temp_list = soup.find_all('span',class_='minMax')
    最后结果都是没有温度信息,打印出来这个:
    [<div class="minMax">
    <div id="maxTempDiv"><img src="http://i.tq121.com.cn/i/weather2017/max.png"/><span id="maxTemp"></span></div>
    <div id="minTempDiv"><img src="http://i.tq121.com.cn/i/weather2017/min.png"/><span id="minTemp"></span></div>
    </div>]
    这种元素提取有没有什么好一点的教程啊?求助!!!!!
    28 条回复    2018-04-12 09:55:17 +08:00
    windfarer
        1
    windfarer  
       2018-04-09 10:45:14 +08:00
    xpath 了解一下
    0vels
        2
    0vels  
       2018-04-09 10:49:29 +08:00
    soup.find('span',id='maxTemp').string 这样应该可以
    F1024
        3
    F1024  
       2018-04-09 11:12:16 +08:00
    xpath
    zbl430
        4
    zbl430  
       2018-04-09 11:43:12 +08:00
    pyquery 也可以看下
    imnpc
        5
    imnpc  
       2018-04-09 11:44:04 +08:00   ❤️ 1
    他这个元素大概是网页加载完成以后 js 操作 dom 写过去的...
    LeIYc
        6
    LeIYc  
    OP
       2018-04-09 11:46:57 +08:00
    @windfarer OK 上网搜到了。
    LeIYc
        7
    LeIYc  
    OP
       2018-04-09 11:49:22 +08:00
    @0vels 为什么。是说除了温度数据以外其他都是标签吗?这什么原理。不是直接写在网页上的吗?是从别的地方取到的?
    LeIYc
        8
    LeIYc  
    OP
       2018-04-09 11:58:29 +08:00
    @0vels 还是不对。打印出了 None。
    shower
        9
    shower  
       2018-04-09 12:04:04 +08:00   ❤️ 1
    用 request-html,执行 JS 之后再取数据
    LeIYc
        10
    LeIYc  
    OP
       2018-04-09 12:14:35 +08:00
    @shower 额。。。具体怎么写?查下好像说数据是 js 生成的。直接取的话取不到?
    johnj
        11
    johnj  
       2018-04-09 13:01:37 +08:00
    看一下页面有没有发 ajax 请求,说不定有
    Vhc001
        12
    Vhc001  
       2018-04-09 13:21:32 +08:00
    @LeIYc 把页面 url 贴出来
    LeIYc
        13
    LeIYc  
    OP
       2018-04-09 13:38:29 +08:00
    mskip
        14
    mskip  
       2018-04-09 13:48:42 +08:00   ❤️ 1
    @LeIYc
    from requests_html import HTMLSession


    session = HTMLSession()
    response = session.get('http://www.weather.com.cn/weather1dn/101280601.shtml')
    response.html.render()
    print(response.html.find('#maxTemp')[0].text)
    rabbbit
        15
    rabbbit  
       2018-04-09 13:48:44 +08:00
    后加载的
    alen
        16
    alen  
       2018-04-09 13:57:59 +08:00
    F12 看 Network
    silencefent
        17
    silencefent  
       2018-04-09 13:59:27 +08:00
    //span[@id='maxtemp']
    //span[@id='mintemp']
    em70
        18
    em70  
       2018-04-09 14:07:23 +08:00
    准备两个函数
    1. 提取两个字符串之间的内容
    2. 提取一个文档内所有这两个字符串之间的内容

    无论什么语言,有这两个函数,可以分析任意文本
    imn1
        19
    imn1  
       2018-04-09 14:10:07 +08:00
    特意加两个 id 标签,后加载可能性极高

    而且天气数据基本按小时为单位更新,多数是 json 更新
    LeIYc
        20
    LeIYc  
    OP
       2018-04-09 14:32:13 +08:00
    谢谢 @rabbbit
    找到了这样的信息:
    var dataSK =
    {"nameen":"shenzhen","cityname":"深圳","city":"101280601","temp":"26","tempf":"78","WD":"西南风","wde":"SW","WS":"2 级","wse":"&lt;12km/h","SD":"54%","time":"13:50","weather":"多云","weathere":"Cloudy","weathercode":"d01","qy":"1009","njd":"30.94km","sd":"54%","rain":"0.0","rain24h":"0","aqi":"71","limitnumber":"","aqi_pm25":"71","date":"04 月 09 日(星期一)"}
    这个应该是正确的。但是怎么才能获取这个信息呢? 直接访问是不行的
    yu099
        21
    yu099  
       2018-04-09 14:34:29 +08:00 via Android
    @LeIYc 打个断点,看哪个 js 加载的啊
    yu099
        22
    yu099  
       2018-04-09 14:35:54 +08:00 via Android
    或者直接 selenium,
    @LeIYc 直接访问的话,你得看一下还带上什么信息的
    woscaizi
        23
    woscaizi  
       2018-04-09 14:40:23 +08:00
    直接带上 cookie 请求接口就 ok 了。
    url: http://d1.weather.com.cn/sk_2d/101280601.html?_=1523255737236
    cookie 类似这样:f_city=%E6%B3%B0%E5%AE%89%7C101120801%7C; Hm_lvt_080dabacb001ad3dc8b9b9049b36d43b=1523255730; Hm_lpvt_080dabacb001ad3dc8b9b9049b36d43b=1523255730; vjuids=2a011e2fb.162a91de08f.0.258106460fa03; vjlast=1523255730.1523255730.30; Wa_lvt_1=1523255731; Wa_lpvt_1=1523255731
    还有就是一些基本的模仿浏览器的配置。
    yuanfnadi
        24
    yuanfnadi  
       2018-04-09 14:40:39 +08:00
    如果只是为了天气数据。可以看一下彩云天气的 api。免费的。
    LeIYc
        25
    LeIYc  
    OP
       2018-04-09 16:08:20 +08:00
    非常感谢大家,发现还是得仔细看一遍书啊。
    《 Python 网络数据采集》这本怎么样,刚下载下来。准备好好看看。
    F0nebula
        26
    F0nebula  
       2018-04-09 16:22:55 +08:00
    jimmyczm
        27
    jimmyczm  
       2018-04-10 10:14:14 +08:00
    直接用 selenium 加载再查找好一点
    from selenium import webdriver

    browser = webdriver.Chrome()
    browser.get('http://www.weather.com.cn/weather1dn/101280601.shtml')
    min = browser.find_element_by_id('maxTempDiv')
    max = browser.find_element_by_id('minTempDiv')
    print(min.text, max.text)
    baday
        28
    baday  
       2018-04-12 09:55:17 +08:00
    看对接口的请求记录,如果直接请求接口能够获取就不用模拟 js 了
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2699 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 35ms · UTC 11:53 · PVG 19:53 · LAX 03:53 · JFK 06:53
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.