Skip to content

Commit e9baffd

Browse files
authored
fix(utils): allow apostrophes and asterisks in extracted URLs (#3790)
Closes #2755 `RequestList`/`requestsFromUrl` extracts URLs from the fetched body with `extractUrls`, which uses `URL_NO_COMMAS_REGEX` / `URL_WITH_COMMAS_REGEX`. The path/query character class of those regexes was missing `'` and `*`, both valid RFC 3986 path sub-delims, so a URL was truncated at the first apostrophe or asterisk. The Zillow example from the issue, `.../141-O'Canoe-Pl-Hertford-NC-27944/...`, came back as `.../141-O`. This adds `'` and `*` to the path/query class of both regexes (no logic changes) so those URLs extract intact. `(` and `)` were already allowed there. Added two `extractUrls` cases (apostrophe, asterisk) that fail before the change and pass after.
1 parent 895ed62 commit e9baffd

2 files changed

Lines changed: 15 additions & 2 deletions

File tree

packages/utils/src/internals/general.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,14 @@ import { setTimeout } from 'node:timers/promises';
66
* and does not support URLs containing commas or spaces. The URLs also may contain Unicode letters (not symbols).
77
*/
88
export const URL_NO_COMMAS_REGEX =
9-
/https?:\/\/(www\.)?([\p{L}0-9]|[\p{L}0-9][-\p{L}0-9@:%._+~#=]{0,254}[\p{L}0-9])\.[a-z]{2,63}(:\d{1,5})?(\/[-\p{L}0-9@:%_+.~#?&/=()]*)?/giu;
9+
/https?:\/\/(www\.)?([\p{L}0-9]|[\p{L}0-9][-\p{L}0-9@:%._+~#=]{0,254}[\p{L}0-9])\.[a-z]{2,63}(:\d{1,5})?(\/[-\p{L}0-9@:%_+.~#?&/=()'*]*)?/giu;
1010

1111
/**
1212
* Regular expression that, in addition to the default regular expression `URL_NO_COMMAS_REGEX`, supports matching commas in URL path and query.
1313
* Note, however, that this may prevent parsing URLs from comma delimited lists, or the URLs may become malformed.
1414
*/
1515
export const URL_WITH_COMMAS_REGEX =
16-
/https?:\/\/(www\.)?([\p{L}0-9]|[\p{L}0-9][-\p{L}0-9@:%._+~#=]{0,254}[\p{L}0-9])\.[a-z]{2,63}(:\d{1,5})?(\/[-\p{L}0-9@:%_+,.~#?&/=()]*)?/giu;
16+
/https?:\/\/(www\.)?([\p{L}0-9]|[\p{L}0-9][-\p{L}0-9@:%._+~#=]{0,254}[\p{L}0-9])\.[a-z]{2,63}(:\d{1,5})?(\/[-\p{L}0-9@:%_+,.~#?&/=()'*]*)?/giu;
1717

1818
let isDockerPromiseCache: Promise<boolean> | undefined;
1919

test/utils/extract-urls.test.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,19 @@ describe('extractUrls()', () => {
9696
expect(extracted).toEqual(array);
9797
});
9898

99+
// https://github.com/apify/crawlee/issues/2755
100+
test('extracts URLs with apostrophes in the path', () => {
101+
const url = "https://www.zillow.com/homedetails/141-O'Canoe-Pl-Hertford-NC-27944/74398007_zpid/";
102+
const extracted = extractUrls({ string: url });
103+
expect(extracted).toEqual([url]);
104+
});
105+
106+
test('extracts URLs with asterisks in the path', () => {
107+
const url = 'https://example.com/path*star/end';
108+
const extracted = extractUrls({ string: url });
109+
expect(extracted).toEqual([url]);
110+
});
111+
99112
test('does not extract invalid URLs', () => {
100113
const { string } = getURLData(INVALID_URL_LIST);
101114
const extracted = extractUrls({ string });

0 commit comments

Comments
 (0)