使用 BeautifulSoup 抓取 Cronometer.com 时遇到问题

时间:2021-06-29 07:58:22

标签: python web-scraping beautifulsoup home-assistant

我对 Python 非常陌生,但使用一些不同的在线指南,我设法将一些代码拼接在一起,将我登录到一个名为 cronometer.com 的网站(健康跟踪网站/应用程序,类似于 myfitnesspal)。不幸的是,我实际上无法抓取任何数据。

我有以下代码(忽略 Hass/AppDaemon,我在 Home Assistant 中运行这个 python 脚本):

import appdaemon.plugins.hass.hassapi as hass
from bs4 import BeautifulSoup
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
import requests

class Scraper(hass.Hass):

  def initialize(self):
    self.log("Scraper Initialized")
    self.get_values(self)

  def get_values(self,kwargs):
    self.login_url = "https://cronometer.com/login/"
    self.r = requests.get(self.login_url)
    self.bs = BeautifulSoup(self.r.text, 'html.parser')
    self.csrf_token = self.bs.find('input', attrs={'name': 'anticsrf'})['value']
    self.url = "https://cronometer.com/"
    self.session = requests.Session()
    self.payload = {
        "username": "MY_USERNAME",
        "password": "MY_PASSWORD",
        "anticsrf": self.csrf_token
    }
    self.headers = {'referer': self.login_url, 'User-agent': 'Chrome'}
    self.sensorname = "sensor.scraper"
    self.friendly_name = "Fasting Status"
    
    try:
      s = self.session.post(self.login_url, data=self.payload, headers=self.headers, cookies=self.r.cookies)
    except:
      self.log("Could not log in")
      return
    
    self.log(self.csrf_token)
    s = self.session.get(self.url)
    page = s.content
    soup = BeautifulSoup(page, "html.parser")

    # Test 1
    fasting1 = soup.select('#cronometerApp > div:nth-child(2) > div:nth-child(1) > div > table > tbody > tr > td:nth-child(1) > div > div:nth-child(8) > div > div.diary-item-title > div')
    self.log("TEST 1")
    self.log(fasting1)

    # Test 2
    fasting2 = soup.select('#cronometerApp > div:nth-child(2) > div:nth-child(1) > div > table > tbody > tr > td:nth-child(1) > div > div:nth-child(8) > div > div.diary-item-content > div.GJES3IWDERB')
    self.log("TEST 2")
    self.log(fasting2)

    # Test 3
    fasting3 = soup.select('#w-node-dd7aab6f-acfc-dfa1-2372-313b5d39fc2b-0dd15747 > div.div__mobile__features-text-1 > h5')
    self.log("TEST 3")
    self.log(fasting3)

    # Test 4
    fasting4 = soup.select('#cronometerApp > div:nth-child(2) > div:nth-child(1) > div > table > tbody > tr > td:nth-child(2) > div > div.GJES3IWDHFD > button:nth-child(1) > span')
    self.log("TEST 4")
    self.log(fasting4)

    # Test 5
    fasting5 = soup.select('#cronometerApp > div:nth-child(2) > div:nth-child(1) > div > table > tbody > tr > td:nth-child(2) > div > div.diary_side_box.GJES3IWDIQB > div.GJES3IWDKQB > div > div.GJES3IWDITE > table > tbody > tr > td > div:nth-child(1) > span')
    self.log("TEST 5")
    self.log(fasting5)

    self.set_state(self.sensorname, state= "Test", attributes = {"friendly_name": self.friendly_name})

据我所知,此代码成功登录 cronometer.com,没有出现任何问题。问题是(我认为)我的个人主页的 URL 与登录前网站的 URL 相同。因此在使用 session.post 将我的凭据发送到网站后,我使用 session.get 从我的“个人资料”中抓取数据。但它只是从普通的 cronometer.com 网页(在您登录之前)抓取数据,而不是我自己的具有相同 URL 的个人网页。

我注意到的一件事是,当我单击顶部的选项卡时,URL 确实会略有变化,如下所示:

enter image description here

当我点击日记时,URL 从 cronometer.com 变为 cronometer.com/#diary,而趋势是 cronometer.com/#trends,依此类推。但事实证明,使用这些特定 URL 也没有成效。

再次抱歉,我缺乏知识,但我该如何克服这个问题?我试过查看一些关于 Selenium 的在线指南,但到目前为止,我一直无法理解如何在问题不一定登录时使用 Selenium 登录(我不认为),但抓取正确的网页。预先感谢您的帮助。

0 个答案:

没有答案