0
    basicInfo = {
    "details": basicSoup.select_one('.basics-description  .basics-text').getText(),
    "dose": basicSoup.select_one('.basics-description .basics-dose').getText(),
    "price": basicSoup.select_one('.basics-description .basics-price').getText(),
    "chemistry": basicSoup.select_one('.basics-description .basics-chemistry').getText(),
    "law": basicSoup.select_one('.basics-description .basics-law').getText(),
    "pharmacology": basicSoup.select_one('.basics-description .basics-pharmacology').getText(),
    "production": basicSoup.select_one('.basics-description .basics-production').getText(),
    "history": basicSoup.select_one('.basics-description .basics-history').getText(),
    "terminology": basicSoup.select_one('.basics-description .basics-terminology').getText(),
    "effects": {
      "text": basicSoup.select_one('.basics-effects .basics-text').getText(),
      "onset": basicSoup.select_one('.basics-effects .basics-onset').getText(),
      "duration": basicSoup.select_one('.basics-effects .basics-duration').getText(),
      "visuals": basicSoup.select_one('.basics-effects .basics-visuals').getText(),
      "crash": basicSoup.select_one('.basics-effects .basics-crash').getText(),
      "hangover": basicSoup.select_one('.basics-effects .basics-hangover').getText(),
    },
    "problems": {
      "text": basicSoup.select_one(".basics-problems > .basics-text").getText(),
    }
  }

I'm trying to figure out what the equivalent of JavaScript's object?.method() is in Python because some pages don't have the information that other pages do so when BeautifulSoup goes to look for them it throws an error.

  File "./chemicalScrape.py", line 48, in <module>
    "crash": basicSoup.select_one('.basics-effects .basics-crash').getText(),
AttributeError: 'NoneType' object has no attribute 'getText'
  • What error are you getting? – Mihai Chelaru Oct 19 '22 at 15:14
  • 3
    Does this help you? https://stackoverflow.com/a/52872515/8627992 – Talon Oct 19 '22 at 15:14
  • @Talon That's a step in the right direction, but now I'm getting an error: Object of type Something is not JSON serializable – Julian Sanchez Oct 19 '22 at 15:24
  • I would suggest to update your question and add your code snippet. From the error message it is visible that `basicSoup.select_one('.basics-effects .basics-crash')` may return `None` value. You could check for the result of that instruction before calling `.getText()`. For your new issue, I guess we need more information. – Farbod Shahinfar Oct 19 '22 at 15:32
  • This is a good example of why functions should usually return the same type or raise an error. Multiple return signatures can be a big pain. There are always exemptions of course.. – Aaron Oct 19 '22 at 15:35
  • @JulianSanchez to get the value from the `Something`/`Nothing`-objects, use the `.get()` method, or the `.or_else()`-method if it could contain `None` – Talon Oct 19 '22 at 15:58

1 Answers1

1

This is verbose compared to object? but you can use getattr() where the third parameter indicates the default value to be returned if the attribute doesn't exist. Since you're about to call it, this should be a function that does nothing. Here you have it written as a lambda:

getattr(obj, "method", lambda: None)()

Break that out into a separate function and generalize it a bit, and you have:

def trycall(obj, method, *args, default=lambda *a, **kw: None, **kwargs):
    return getattr(obj, method, default)(*args, **kwargs)

Using your example:

# basicSoup.select_one('.basics-effects .basics-crash').getText()
trycall(basicSoup.select_one(('.basics-effects .basics-crash'), "getText")
kindall
  • 178,883
  • 35
  • 278
  • 309