Python|Python爬虫-获得某一链接下的所有超链接

Python爬虫-获得某一链接下的所有超链接
目录

  • Python爬虫-获得某一链接下的所有超链接
    • 用到的库
    • 具体实现:
      • 1. 获得某页面的html内容
      • 3.获得某html下的所有超链接
      • 4.筛除结果中非链接的元素
      • 主程序
    • 大功告成!

用到的库 【Python|Python爬虫-获得某一链接下的所有超链接】Beautifulsoup4、requests、re模块
import requests as rq from bs4 import BeautifulSoup as bs import re

具体实现: 1. 获得某页面的html内容
要获得某一个页面的html,没什么好说,直接调用request库吧!
要注意的是这里request.get()返回的是一个response类型,但是这个类其实是包括了我们需要的html信息的,只需要调用该类的text()方法即可返回网页的源代码。
def gethtml(rooturl, encoding="utf-8"): # 默认解码方式utf-8 response = rq.get(rooturl) response.encoding = encoding html = response.text return html# 返回链接的html内容

3.获得某html下的所有超链接
现在我们获得了某一个网址的源代码,学过html或者数据结构的同学都很容易知道,我们要找的超链接一般是藏在DOM树的a节点下的。
这是树结构逻辑上的示意图:
Python|Python爬虫-获得某一链接下的所有超链接
文章图片

在实际的html文件中,即为如下所示的地方(节点):
Python|Python爬虫-获得某一链接下的所有超链接
文章图片

现在我们知道了超链接在html中所处的位置,可是该如何获取他们呢?一种方法是使用正则表达式把html当成字符串暴力处理,思路上就是类似if “” in html的模式;另外一种是我们可以调用BeautifulSoup库强大的解析功能,让他帮我们定位,不过这样我们还需遵循如下的语法细节:
  1. BeautifulSoup()函数返回的是一个解析过的对象,相当于把你的html文本做了处理;
  2. 调用这个解析过的对象的find_all()方法,即返回一个该html中 所有的a节点组成的列表;
  3. 再对表中每一个节点调用get()方法,获得该节点下"herf"标签(键)的所有值,也就是我们的要找“http://”打头的超链接了;
def getherf(html): # 使用BeautifulSoup函数解析传入的html soup = bs(html, features="lxml") allnode_of_a = soup.find_all("a") result = [_.get("href") for _ in allnode_of_a] # print(result) return result

4.筛除结果中非链接的元素
实际应用过程中我们会发现,有些herf的值并不是我们要找的超链接,而是其他的文本:
Python|Python爬虫-获得某一链接下的所有超链接
文章图片

这就导致获取到的result中还包含一些奇怪的东西:
Python|Python爬虫-获得某一链接下的所有超链接
文章图片

如此,我们就需要对获得的结果进行一次筛查,排除不需要的元素并保留链接,那这里比较直接的方法就是使用前面提到的正则化,简单来说,"http://"打头的就留下,否则就删除:
  • re.match(pattern, string)可以接收两个参数,前者是模式后者是待匹配字符,形象地理解为:通过re.match(长得高,一堆女的)来找我的理想型女朋友,那得先有要求才能相亲啊;
  • urlptn即匹配模式,单独的“.”表示除\n外的所有单字符,(.+)就表示http://后面的单字符重复1次或多次;
  • 但是re.macth()返回的并不直接是我们需要的链接,倘若匹配成功,我们需要对获得的对象(长得高的更可能成为对象 (大雾))调用group()方法来获得字符串,即为链接;
  • 这么做的问题是:若匹配失败,返回的none也在表中了,但是none没有group方法,程序就会报错,那我们只需要在逐个调用group前筛除所有none就好了,我这里采用的是while循环的办法。
def filterurl(result): # result参数:get到的所有a标签内herf的内容 # 对列表中每个元素进行筛选 urlptn = r"http://(.+)"# 匹配模式: 所有http://开头的链接 urls = [re.match(urlptn, str(_)) for _ in result]# 正则筛选 # print(urls) while None in urls: urls.remove(None)# 移除表中空元素 urls = [_.group() for _ in urls]# group方法获得re.match()返回值中的字符 # print(urls) return urls

主程序
html = gethtml("http://huxi.cqu.edu.cn/") result = getherf(html) urls = filterurl(result) print(urls)

大功告成! Python|Python爬虫-获得某一链接下的所有超链接
文章图片

这样一来我们就完成了对某一网址的所有超链接的提取,后续再顺藤摸瓜来爬取被指向的网站就容易很多了。当然对某一网站的其他内容(图片,音频,电子书等)的提取也大同小异,例如有的网站的图片链接是储存在img节点下的,即img节点的src键对应的值,那我们只需要简单修改定位的函数即可。

    推荐阅读