From 622529b9ae3187d21081cb140018038cb9d5a84b Mon Sep 17 00:00:00 2001 From: Lorenzo Di Fuccia Date: Thu, 3 Jan 2019 14:30:14 +0100 Subject: [PATCH] Fixed #51 Fixed #56 Fixed #58 Fixed #59 Fixed #61 --- safaribooks.py | 63 ++++++++++++++++++++++++++------------------------ 1 file changed, 33 insertions(+), 30 deletions(-) diff --git a/safaribooks.py b/safaribooks.py index d6b6df9..1f96b94 100644 --- a/safaribooks.py +++ b/safaribooks.py @@ -18,6 +18,10 @@ from urllib.parse import urljoin, urlsplit, urlparse PATH = os.path.dirname(os.path.realpath(__file__)) COOKIES_FILE = os.path.join(PATH, "cookies.json") +SAFARI_BASE_HOST = "learning.oreilly.com" +SAFARI_BASE_URL = "https://" + SAFARI_BASE_HOST + + class Display: BASE_FORMAT = logging.Formatter( @@ -145,11 +149,11 @@ class Display: ) def done(self, epub_file): - self.info("Done: %s\n\n" + self.info("Done: %s\n\n" % epub_file + " If you like it, please * this project on GitHub to make it known:\n" " https://github.com/lorenzodifuccia/safaribooks\n" " e don't forget to renew your Safari Books Online subscription:\n" - " https://www.safaribooksonline.com/signup/\n\n" % epub_file + + " " + SAFARI_BASE_URL + "\n\n" + self.SH_BG_RED + "[!]" + self.SH_DEFAULT + " Bye!!") @staticmethod @@ -158,7 +162,7 @@ class Display: if "detail" in response and "Not found" in response["detail"]: message += "book's not present in Safari Books Online.\n" \ " The book identifier is the digits that you can find in the URL:\n" \ - " `https://www.safaribooksonline.com/library/view/book-name/XXXXXXXXXXXXX/`" + " `" + SAFARI_BASE_URL + "/library/view/book-name/XXXXXXXXXXXXX/`" else: os.remove(COOKIES_FILE) @@ -179,6 +183,9 @@ class WinQueue(list): # TODO: error while use `process` in Windows: can't pickl class SafariBooks: + LOGIN_URL = SAFARI_BASE_URL + "/accounts/login/" + API_TEMPLATE = SAFARI_BASE_URL + "/api/v1/book/{0}/" + HEADERS = { "accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8", "accept-encoding": "gzip, deflate", @@ -186,16 +193,13 @@ class SafariBooks: "cache-control": "no-cache", "cookie": "", "pragma": "no-cache", - "referer": "https://www.safaribooksonline.com/home/", + "origin": SAFARI_BASE_URL, + "referer": LOGIN_URL, "upgrade-insecure-requests": "1", - "user-agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) " - "Chrome/62.0.3202.94 Safari/537.36" + "user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) " + "Chrome/60.0.3112.113 Safari/537.36" } - BASE_URL = "https://www.safaribooksonline.com" - LOGIN_URL = BASE_URL + "/accounts/login/" - API_TEMPLATE = BASE_URL + "/api/v1/book/{0}/" - BASE_01_HTML = "\n" \ "" # Format: ID, Depth, Title, Author, NAVMAP - TOC_NCX = "" \ + TOC_NCX = "\n" \ "" \ - "" \ - "" \ - "" \ - "" \ - "" \ - "" \ - "" \ - "{2}" \ - "{3}" \ - "{4}" \ + " \"http://www.daisy.org/z3986/2005/ncx-2005-1.dtd\">\n" \ + "\n" \ + "\n" \ + "\n" \ + "\n" \ + "\n" \ + "\n" \ + "\n" \ + "{2}\n" \ + "{3}\n" \ + "{4}\n" \ "" def __init__(self, args): @@ -364,7 +368,7 @@ class SafariBooks: return " ".join(["{0}={1};".format(k, v) for k, v in self.cookies.items()]) def return_headers(self, url): - if "safaribooksonline" in urlsplit(url).netloc: + if SAFARI_BASE_HOST in urlsplit(url).netloc: self.HEADERS["cookie"] = self.return_cookies() else: @@ -441,10 +445,9 @@ class SafariBooks: self.LOGIN_URL, post=True, data=( - ("csrfmiddlewaretoken", ""), ("csrfmiddlewaretoken", csrf), + ("csrfmiddlewaretoken", csrf), ("email", email), ("password1", password), - ("is_login_form", "true"), ("leaveblank", ""), - ("dontchange", "http://") + ("login", "Sign In"), ("next", "") ), allow_redirects=False ) @@ -531,7 +534,7 @@ class SafariBooks: root = None try: - root = html.fromstring(response.text, base_url=self.BASE_URL) + root = html.fromstring(response.text, base_url=SAFARI_BASE_URL) except (html.etree.ParseError, html.etree.ParserError) as parsing_error: self.display.error(parsing_error) @@ -591,7 +594,7 @@ class SafariBooks: return None def parse_html(self, root, first_page=False): - if random() > 0.5: + if random() > 0.8: if len(root.xpath("//div[@class='controls']/a/text()")): self.display.exit(self.display.api_error(" ")) @@ -798,7 +801,7 @@ class SafariBooks: self.display.images_ad_info.value = 1 else: - response = self.requests_provider(urljoin(self.BASE_URL, url), + response = self.requests_provider(urljoin(SAFARI_BASE_URL, url), update_cookies=False, stream=True) if response == 0: @@ -1004,7 +1007,7 @@ if __name__ == "__main__": arguments.add_argument( "bookid", metavar='', help="Book digits ID that you want to download. You can find it in the URL (X-es):" - " `https://www.safaribooksonline.com/library/view/book-name/XXXXXXXXXXXXX/`" + " `" + SAFARI_BASE_URL + "/library/view/book-name/XXXXXXXXXXXXX/`" ) args_parsed = arguments.parse_args()