Fetching Web Content with urllib
Fetching web content for URL extraction involves two connected tasks.
From HTML to URLs
Fetching web content for URL extraction involves two connected tasks. First, a program obtains HTML content with urllib. Next, a regular expression searches that HTML and isolates the URL text. The important mechanism in the extraction step is the capturing group: parentheses identify the part of a larger match that should be returned.
A regular expression can match a larger HTML fragment while a capturing group selects only the substring you want to extract.
Capturing the URL Text
Consider the generated pattern <a href="(.*?)">. The pattern describes an anchor-like HTML fragment. The parentheses around .*? create a capturing group. The complete match includes the surrounding HTML text, but the captured substring is the text between the opening quote after href= and the next closing quote. The question mark makes the repetition non-greedy, so .*? stops at the first closing quote rather than consuming too much text.
Tracing findall Results
Extracting two links
Apply the pattern <a href="(.*?)"> to the generated HTML fragment <a href="/home">Home</a><a href="/about">About</a>.
- 1Locate the first match
The pattern matches the first anchor-like fragment and the capturing group contains /home.
- 2Continue through the HTML
The search continues after the first matching fragment and finds the second one. Its capturing group contains /about.
- 3Return the captured values
Because the pattern has a capturing group,
re.findall()returns the captured URL text rather than the complete matching HTML fragments.
The extracted values are /home and /about.
['/home', '/about']re.findall() is useful here because its result consists of the captured groups. The surrounding anchor text is used to identify each match but is not returned as the extracted URL when the group is present.
Request and Certificate Context
The extraction pattern operates on HTML content obtained by the web request. When the target site has an invalid certificate, certificate verification must be disabled in the fetching code by using an SSL context. The context belongs to the request stage; once HTML has been obtained, the regular expression processes that HTML separately.
Debugging a Failed Match
When URL extraction fails, compare the pattern with the actual HTML rather than assuming that the pattern describes the input correctly. Trace where the pattern begins matching, what text the group captures, and where the non-greedy expression stops. If the actual HTML differs from the expected anchor-like structure, the pattern may stop matching before a URL is captured or may produce a different captured substring.
Common mistake Leaving out the capturing parentheses.
What it looks likeUsing a pattern that describes the link but does not place parentheses around the URL portion.
Why it failsThe extraction no longer identifies the URL substring as a captured group for
re.findall()to return.Do this insteadPlace parentheses around the part of the match that should become the extracted URL.
Common mistake Using a greedy wildcard instead of .*?.
What it looks likeUsing .* between the opening and closing quotes.
Why it failsThe expression can match too much instead of stopping at the first closing quote.
Do this insteadUse the non-greedy quantifier .*? for this URL-extraction pattern.
Common mistake Debugging only the regular expression and not the input HTML.
What it looks likeAssuming every link begins exactly with <a href=".
Why it failsA pattern can fail when the actual HTML differs from the structure it expects.
Do this insteadInspect the actual HTML and trace the first point where it differs from the pattern.
Common mistake Treating certificate problems as regex problems.
What it looks likeChanging the capturing group when the web request cannot obtain the HTML because of an invalid certificate.
Why it failsCertificate verification occurs during fetching, before regex processing.
Do this insteadConfigure an SSL context for the request when fetching from a site with an invalid certificate.
A Reliable Debugging Routine
- 1Confirm that the web request produced HTML content. If the site has an invalid certificate, review the SSL context used for the request.
- 2Write down the exact HTML fragment that should contain a URL.
- 3Mark the opening and closing boundaries that the pattern expects.
- 4Check that parentheses surround the substring to be returned.
- 5Check that .*? is used when the match must stop at the first closing quote.
- 6Run
re.findall()and inspect the returned captured values. - 7If the result is empty or unexpected, compare the first failed HTML fragment with the pattern character by character.
For the generated HTML fragment <a href="/docs">Docs</a><a href="/contact">Contact</a>, identify the two strings that should be returned by re.findall() when the pattern is <a href="(.*?)">. Then explain why the complete anchor text is not returned.
Hints
- Find the text between each pair of quotes after href=.
- The parentheses identify the captured part of each match.
- The surrounding <a href=" and "> text helps define the match but is not the captured URL.
Key Takeaways
- 1Parentheses create capturing groups that isolate a substring from a larger regular-expression match.
- 2The non-greedy quantifier .*? helps URL extraction stop at the first closing quote.
- 3
re.findall()returns the captured groups, making it suitable for collecting URLs from matching HTML fragments. - 4Regex debugging requires comparing the expected pattern with the actual HTML and tracing each match.
- 5An SSL context is used at the fetching stage when certificate verification must be disabled for a site with an invalid certificate.
At a glance
- Capturing parentheses determine which substring is extracted from a larger HTML match.
- Use .*? so URL matching stops at the first closing quote rather than matching too much.
re.findall()returns the captured URL values instead of the entire matching tags.- Compare the pattern with actual HTML when extraction fails.
- Use an SSL context during fetching when a target site has an invalid certificate.