69 lines
2.3 KiB
Python
69 lines
2.3 KiB
Python
import requests
|
|
from bs4 import BeautifulSoup
|
|
from selenium import webdriver
|
|
|
|
from User import User
|
|
from Submission import Submission
|
|
from Comment import Comment
|
|
|
|
FA_BASE_URL = 'https://furaffinity.net'
|
|
|
|
|
|
class FAAPI:
|
|
"""
|
|
A basic FurAffinity API instance.
|
|
"""
|
|
|
|
def __init__(self, use_webdriver: bool = True):
|
|
"""
|
|
Initialises a new FAAPI instance.
|
|
Beware that a Chrome instance is launched to bypass Cloudflare and log in during initialisation. Change use_webdriver to False to disable this.
|
|
"""
|
|
|
|
if not use_webdriver:
|
|
# Can't do any actual API things, stop here
|
|
return
|
|
|
|
# Try sign in to FA
|
|
self._driver = webdriver.Chrome()
|
|
self._driver.get(FA_BASE_URL + '/login')
|
|
|
|
# Wait until our username is visible on the top banner
|
|
while not self._driver.find_elements_by_id('my-username'):
|
|
pass
|
|
|
|
# Save the username of the account we've logged in as
|
|
self.username = self._driver.find_elements_by_css_selector('#my-username:not(.hideondesktop)')[0].text.strip()
|
|
|
|
# Extract the cookies and stop the driver
|
|
self._cookies = self._driver.get_cookies()
|
|
self._driver.close()
|
|
|
|
# Set up a Requests session with the cookies we just got
|
|
self._req = requests.session()
|
|
[self._req.cookies.set(cookie['name'], cookie['value']) for cookie in self._cookies]
|
|
|
|
def get_user(self, username: str) -> User:
|
|
soup = self.get_soup('{}/user/{}/'.format(FA_BASE_URL, username))
|
|
|
|
try:
|
|
# Try extract the username, stripping the ~/∞/! in front
|
|
username = soup.select('div.username h2')[0].text.strip()[1:]
|
|
except IndexError:
|
|
# No username, give up
|
|
return None
|
|
|
|
return User.new_or_cached(self, username)
|
|
|
|
def get_soup(self, url: str) -> BeautifulSoup:
|
|
"""
|
|
Gets a webpage and wraps it in a BeautifulSoup instance.
|
|
:param url: Webpage URL
|
|
:return: Webpage wrapped in a BeautifulSoup instance
|
|
"""
|
|
res = self._req.get(url)
|
|
if res.status_code >= 400:
|
|
raise Exception(
|
|
'Got status code {} when trying to get URL {}'.format(res.status_code, url))
|
|
return BeautifulSoup(res.content, 'lxml')
|