Clean up goodreads search function

This commit is contained in:
Evan Fiordeliso 2025-06-26 13:22:39 -04:00
parent f2ac5736b2
commit 785ca0e884
1 changed files with 29 additions and 36 deletions

View File

@ -206,41 +206,44 @@ export async function searchBooks(q: string): Promise<SearchResult[]> {
const url = "https://www.goodreads.com/search?q=" + encodeURIComponent(q); const url = "https://www.goodreads.com/search?q=" + encodeURIComponent(q);
const res = await requestUrl({ url }); const res = await requestUrl({ url });
const doc = new DOMParser().parseFromString(res.text, "text/html"); const doc = new DOMParser().parseFromString(res.text, "text/html");
const bookElements = doc.querySelectorAll(
return Array.from(
doc.querySelectorAll(
"table.tableList tr[itemtype='http://schema.org/Book']" "table.tableList tr[itemtype='http://schema.org/Book']"
); )
).map<SearchResult>((el) => {
const searchResults: SearchResult[] = [];
bookElements.forEach((el) => {
const legacyId = parseInt( const legacyId = parseInt(
el.querySelector("div.u-anchorTarget")?.id ?? "", el.querySelector("div.u-anchorTarget")?.id ?? "",
10 10
); );
const title = el.querySelector("a.bookTitle")?.textContent?.trim();
const authors = Array.from(el.querySelectorAll("a.authorName")) const title =
.map((a) => a.textContent?.trim() || "") el.querySelector("a.bookTitle")?.textContent?.trim() || "";
.join(", ");
const coverImageUrl = el const authors = Array.from(el.querySelectorAll("a.authorName")).map(
.querySelector("img.bookCover") (a) => a.textContent?.trim() || ""
?.getAttribute("src"); );
const avgRating = parseFloat( const avgRating = parseFloat(
el el
.querySelector("span.minirating") .querySelector("span.minirating")
?.textContent?.match(/(\d+\.\d+) avg rating/)?.[1] ?? "0" ?.textContent?.match(/(\d+\.\d+) avg rating/)?.[1] ?? "0"
); );
const ratingCount = parseInt( const ratingCount = parseInt(
el el
.querySelector("span.minirating") .querySelector("span.minirating")
?.textContent?.match(/(\d[\d,]*) ratings/)?.[1] ?? "0", ?.textContent?.match(/(\d[\d,]*) ratings/)?.[1] ?? "0",
10 10
); );
const publicationYear = parseInt( const publicationYear = parseInt(
el el
.querySelector("span.greyText") .querySelector("span.greyText")
?.textContent?.match(/published (\d{4})/)?.[1] ?? "0", ?.textContent?.match(/published (\d{4})/)?.[1] ?? "0",
10 10
); );
const editionCount = parseInt( const editionCount = parseInt(
el el
.querySelector("span.greyText") .querySelector("span.greyText")
@ -248,28 +251,18 @@ export async function searchBooks(q: string): Promise<SearchResult[]> {
10 10
); );
if ( const coverImageUrl =
!isNaN(legacyId) && el.querySelector("img.bookCover")?.getAttribute("src") || "";
title &&
authors && return {
!isNaN(avgRating) &&
!isNaN(ratingCount) &&
!isNaN(publicationYear) &&
!isNaN(editionCount) &&
coverImageUrl
) {
searchResults.push({
legacyId, legacyId,
title, title,
authors: authors.split(", "), authors,
avgRating, avgRating,
ratingCount, ratingCount,
publicationYear, publicationYear,
editionCount, editionCount,
coverImageUrl, coverImageUrl,
};
}); });
} }
});
return searchResults;
}