Python解析HTML响应异常:使用Request对象无法提取HTTP链接
解决Google搜索结果链接提取无返回的问题
Hey Kris, 我一眼就看出问题出在哪了!
你测试牛津大学页面时能拿到链接,是因为那个页面的<a href>里直接放的是完整的http开头URL,但Google搜索结果的链接格式完全不一样——为了做跳转追踪,Google把真实链接藏在了/url?q=xxx这样的href里。而你的get_all_links函数只筛选href开头是h的链接,Google的href开头是/,自然不会被匹配到,所以返回空列表啦。
下面给你两种解决方案:
方案1:修改现有字符串逻辑适配Google格式
不用换库,调整一下链接提取的判断逻辑就行,专门处理Google的跳转链接:
import urllib.request import urllib.parse def get_all_links(s): links = [] d = 0 while d != -1: d = s.find('<a href=', d) if d == -1: break start = s.find('"', d) end = s.find('"', start + 1) if start == -1 or end == -1: d += 1 continue href = s[start+1:end] # 处理Google的跳转链接 if href.startswith('/url?q='): # 解析出真实的目标URL real_url = urllib.parse.unquote(href.split('?q=')[1].split('&')[0]) links.append(real_url) # 保留原本支持的http开头链接 elif href.startswith('http'): links.append(href) d = end + 1 return links def main(): term = input('Enter a search term: ') url = 'http://www.google.com/search' value = {'q' : term} user_agent = 'Mozilla/5.0' headers = {'User-Agent' : user_agent} data = urllib.parse.urlencode(value) url = url + '?' + data req = urllib.request.Request(url, None, headers) content = urllib.request.urlopen(req) s = content.read().decode('utf-8') links = get_all_links(s) for i in links: print(i) main()
方案2:用专业HTML解析库(更推荐!)
手动用字符串查找HTML真的太脆弱了,哪天Google改一下页面结构,你的代码又会失效。推荐用BeautifulSoup这个专门的HTML解析库,它能更稳定地提取元素:
首先先安装库:
pip install beautifulsoup4
然后替换成下面的代码:
import urllib.request import urllib.parse from bs4 import BeautifulSoup def get_all_links(html_content): links = [] soup = BeautifulSoup(html_content, 'html.parser') # 遍历所有带href属性的a标签 for a_tag in soup.find_all('a', href=True): href = a_tag['href'] if href.startswith('/url?q='): # 解析跳转链接里的真实URL real_url = urllib.parse.unquote(href.split('?q=')[1].split('&')[0]) links.append(real_url) elif href.startswith('http'): links.append(href) return links def main(): term = input('Enter a search term: ') url = 'http://www.google.com/search' value = {'q' : term} user_agent = 'Mozilla/5.0' headers = {'User-Agent' : user_agent} data = urllib.parse.urlencode(value) url = url + '?' + data req = urllib.request.Request(url, None, headers) content = urllib.request.urlopen(req) html = content.read().decode('utf-8') links = get_all_links(html) for link in links: print(link) main()
这样修改后,不管是Google搜索结果还是普通网站的链接,都能稳稳提取出来啦。
内容的提问来源于stack exchange,提问作者Kris
相关产品推荐
相关产品推荐

