外链对SEO的重要性到今天我想已经不用多说了,友情链接则是我们在优化过程中毕竟经常使用的一种增加外链方法,不过外链还是需要定期的检查的,毕竟一些站长下链卖站了可能不一定会提醒…或者有的网站已经不续费了,域名过期被抢注,直接做灰黑产业站点,我们又没下链,那么排名可能就会直接消失..哈哈哈,但是我们网站多了,又不可能一个个人工去检查,像我之前公司以前SEO订单多的时候要优化100+站点,自己又有一些网站,要是一个个查,那真是要不少时间的,所以我们可以使用Python批量检查网站友情链接,来提高我们的工作效率,下面先看下简单的流程,然后直接放代码:
流程分析
我们通常检查友链的流程如下:
- 访问网站
- 查看友链
- 查看友链网站
- 检查是否互链接
- 其他检查…
实现代码
# -*- coding: utf-8 -*-
"""
# 需求
# 批量查询友情链接状态
# 流程
# 请求、下载自身站点网页
# 提取友链
# 查询每个友链状态
# 输出/保存检查结果
"""
import re
import time
import requests
from bs4 import BeautifulSoup
from threading import Thread
class LinkQuery(Thread):
def __init__(self, site_link: str):
"""
:param site_link: 查询网站链接
"""
super(LinkQuery, self).__init__()
# 初始化查询域名
self.site_link = site_link
# 查询域名去除协议头 用于过滤、查询本站域名以及保存文件使用
self.site_domain = self.get_domain(self.site_link)
# 获取请求头
self.headers = {
'User-Agent': 'Mozilla/5.0 (compatible; Baiduspider-render/2.0; +http://www.baidu.com/search/spider.html)'
}
def run(self) -> None:
# 获取网页源码
html = self.download(self.site_link)
if html is None:
print(self.site_link + '结果为空 请检查!!!')
with open('访问错误链接.txt', 'a', encoding='utf-8') as link_f:
link_f.write(self.site_link + '\n')
return None
# 提取链接
links_set = self.extract_a_tag(html)
links_set = (_ for _ in links_set if self.site_domain not in _) # 去除本站链接
# 查询是否互链
link_count, mutual_info = self.query_start(links_set)
# 保存结果
self.save_file(link_count, mutual_info)
@staticmethod
def initiate_link(_link):
"""
链接优化处理
1:去除链接开头和结尾空格、空行和结尾/符号
2:若无协议头则增加http协议头 否则直接返回
"""
_link = _link.strip()
_link = _link.rstrip('/')
if _link.startswith('//'):
return 'http:' + _link
elif not _link.startswith('http'):
return 'http://' + _link
else:
return _link
@staticmethod
def get_domain(_link):
"""
对域名去除协议头处理 避免因为协议头导致的错误
:param _link:
:return:
"""
_link = re.sub('https://|http://|\s|/', '', _link)
return _link
def download(self, link: str, retires: int = 2):
"""
源码下载函数
:param link: 查询的站点
:param retires: 超时重试的次数
:return: 网页源码
"""
link = self.initiate_link(link) # 链接优化处理
try:
r = requests.get(link, headers=self.headers, timeout=5)
except requests.Timeout:
html = None
if retires > 0:
return self.download(link, retires - 1)
except requests.RequestException as e:
print('出现错误,链接:', link, '\n', e)
return None
else:
if not r.status_code == 200:
return None
r.encoding = 'UTF-8'
html = r.text
return html
@staticmethod
def generate_soup(html_doc):
"""
将HTML生成BeautifulSoup对象
:param html_doc: HTML
:return: BeautifulSoup对象
"""
_soup = BeautifulSoup(html_doc, 'html.parser')
return _soup
@staticmethod
def custom_filter(a_tag):
"""
链接过滤函数
:param a_tag: BeautifulSoup元素对象(a标签)
:return:
"""
if a_tag.get("href"):
link = a_tag["href"]
if not link.startswith("http"):
return False
if a_tag.get("rel") and "nofollow" in a_tag.get("rel"):
return False
return True
return False
def extract_a_tag(self, html_content: str):
"""
网页源码链接提取
:param html_content: 网页源码
:return: 提取到的链接
"""
soup = self.generate_soup(html_content)
all_a_tag = soup.find_all('a', href=True)
_links_set = set()
for a_tag in all_a_tag:
if self.custom_filter(a_tag):
_links_set.add(a_tag["href"])
return _links_set
def query_start(self, yq_links: set):
"""
是否互链查询函数
:param yq_links: 站点提取到的链接
:return: 异常链接数, 结果字典
"""
link_count = 0
mutual_info = dict()
yq_links = set(yq_links) # 集合去重
print(f'访问正常, 提取{len(yq_links)}个链接, 开始检测链接情况')
# print(yq_links)
# 循环请求处理后的域名 判断是否存在本站链接
for yq_link in yq_links:
yq_link_content = self.download(yq_link)
if yq_link_content is None:
print(yq_link, '访问错误')
link_count += 1
mutual_info[yq_link] = '访问错误'
continue
# 提取链接
_links_set = self.extract_a_tag(yq_link_content)
if not self.site_link in _links_set:
link_count += 1
mutual_info[yq_link] = '无互链'
return link_count, mutual_info
@staticmethod
def save_file(link_count, link_state):
"""
结果保存函数
:param link_count: query_start()返回的异常链接数量
:param link_state: query_start()返回的异常链接结果字典
:return:
"""
# 直接输出 不保存了 需要可以自己完善
if link_state:
print(f'提取到{link_count}个异常链接', link_state)
else:
print('未提取到异常链接')
def main():
start_time = time.time()
query_site_link = ['https://www.linfengnet.com']
for site_link in query_site_link:
site_link = site_link.strip()
print(f'当前查询站点:{site_link}')
task = LinkQuery(site_link)
task.start()
print('查询完毕 耗时:', time.time() - start_time)
if __name__ == '__main__':
main()
你只需要把你要检查的网站,都加入到query_site_link = [‘https://www.linfengnet.com’]这行代码中,每个网站网址都用英文单引号包起来,然后用英文逗号分隔…
也可以把所有链接都放到一个txt文件中,一行一个,然后读取…
实现代码我就不贴了,毕竟代码优化下去是没玩完了的,上面说的也只是很基础的Python知识,如果你学了不需要我说都知道…
如果你对Python感兴趣,就可以看看我之前分享的Python学习资料,学完你就可以自己优化代码了,下面提到的深入优化的建议也可以自己实现:Python入门学习资料推荐
深入优化
上面的代码实现的只是比较简单的功能,查询网站之间是否互相链接,根据我的经验还可以完善下面这些功能:
- 检查网站是否备案
- 毕竟国内搜索引擎对一些不备案的网站抓取都不咋抓取>而且一些不备案的很容易做灰黑站点
- 检查网站是否收录>如果网站连收录都没有>有可能被K了,如果你换的时候没检查收录,现在看到这个情况,也可以考虑下了。
- nofollow链接细分显示
- 上面版本中会过滤掉nofollow链接,这个步骤本身没问题,不过会显示为无互链的状态,你可以改造显示为对方nofollow的状态,然后对这个换链nofollow的人输出一顿…
- 批量查询的已放链接忽略
- 假设你要查询30个网站,但是它们直接有部分是单向链接,自己的网站可以忽略,你也可以增加这个功能…
- 制作可视化软件版本…
- 其他…
付费版本
实际在应用过程中还是会有一些的’个性化需求’要解决的…要根据你网站的实际情况去解决,不过你放心,上面示例代码是足够对大部分的网站进行使用的,一些奇奇怪怪的情况肯定是无法做到兼容的,深入优化中提到的大部分功能我也实现了,如果你有意向购买的话,可以联系我获取软件版本…也可以根据你网站的时间情况给出对应版本的软件。