Python爬虫:《Web Scraping with Python》第3章getInternalLinks函数疑问
函数核心实现逻辑
你关注的这行代码for link in bs.find_all('a', href=re.compile('^(/|.*'+includeUrl+')')):是整个站内链接筛选的核心规则。在函数提前通过urlparse把传入的URL处理成协议+根域名格式(例如将https://stackoverflow.com/questions/ask处理为https://stackoverflow.com)后,正则会匹配两类符合要求的href值:
- 第一类:以
/开头的根相对路径链接,命中^/正则分支 - 第二类:href字符串中包含上述处理后的根域完整前缀的绝对链接,命中
^.*[根域地址]正则分支
这个函数并不是只能匹配不完整的相对链接,设计上就是同时覆盖两种常见的站内链接写法。后续的代码逻辑完全对应这个匹配规则:
- 对筛选出的、以
/开头的相对链接,自动拼接提前提取的根域地址,补成完整可访问的URL存入结果列表 - 对筛选出的、带根域前缀的绝对链接,不需要额外拼接,直接存入结果列表
- 全流程自动去重,同一个链接不会在返回结果中重复出现
实际匹配效果对照
以函数处理后的根域includeUrl = https://stackoverflow.com为例,不同href值的处理结果如下:
- 会被正常抓取的站内链接
- 相对路径类:例如href值为
/questions、/users/login,会被正则第一分支命中,代码自动拼接为https://stackoverflow.com/questions、https://stackoverflow.com/users/login存入结果 - 绝对路径类:例如href值为
https://stackoverflow.com/tags、https://stackoverflow.com/jobs,会被正则第二分支命中,因本身已是完整URL,直接存入结果
- 相对路径类:例如href值为
- 不会被处理的站外链接(例如你提到的
https://www.facebook.com)
这类链接既不满足以/开头的规则,href字符串中也不包含当前站点的根域字符串,从bs.find_all的第一步筛选就被排除,完全不会进入后续的属性判断、路径拼接流程。
该示例代码为书籍简化设计,存在部分场景覆盖盲区:例如不会匹配同目录下不带斜杠开头的相对链接(如
ask、profile/123),也不会匹配带子域变体的链接(如https://www.stackoverflow.com),这类场景在生产环境的爬虫实现中需要额外补全规则,不影响对核心设计逻辑的理解。
函数正确使用方式
- 调用时不需要手动处理传入的URL格式,直接将当前爬取页面的任意完整URL、以及解析完成的BeautifulSoup对象传入函数即可,函数内部会自动完成根域提取、链接筛选、路径补全、去重全流程
- 函数返回的列表就是当前页面上所有符合规则的站内链接集合,可直接用于后续的爬虫遍历逻辑
内容的提问来源于stack exchange,提问作者Arthur Speiser
相关产品推荐
相关产品推荐

