__ _ __
____ _____ ____ / /______ _ _________ (_)___/ /__ _____
/ __ `/ __ \______/ __ \/ //_/ __ `/_____/ ___/ __ \/ / __ / _ \/ ___/
/ /_/ / /_/ /_____/ /_/ / ,< / /_/ /_____(__ ) /_/ / / /_/ / __/ /
\__, /\____/ / .___/_/|_|\__, / /____/ .___/_/\__,_/\___/_/
/____/ /_/ /____/ /_/
一个 Golang 实现的相对智能、无需规则维护的通用新闻网站数据提取工具库。含域名探测、网页编码语种识别、网页链接分类提取、网页新闻要素抽取以及新闻正文抽取等组件。
前往 go-pkg-spider-gui Releases 下载支持 Windows、MacOS GUI 客户端,进行体验。
go get -u github.com/suosi-inc/go-pkg-spider
Http 客户端对 go-fun 中的 fun.HttpGet
相关函数进行了一些扩展,增加了以下功能:
- 自动识别字符集和转换字符集,统一转换为 UTF-8
- 响应文本类型限制
HttpGet(urlStr string, args ...any) ([]byte, error)
Http Get 请求HttpGetResp(urlStr string, r *HttpReq, timeout int) (*HttpResp, error)
Http Get 请求, 返回 HttpResp
当前支持以下主流语种:中文、英语、日语、韩语、俄语、阿拉伯语、印地语、德语、法语、西班牙语、葡萄牙语、意大利语、泰语、越南语、缅甸语。
语种识别通过 HTML 、文本特征、字符集统计规则优先识别中文、英语、日语、韩语。
同时辅助集成了 lingua-go n-gram model 语言识别模型,fork 并移除了很多语种和语料(因为完整包很大)
LangText(text string) (string, string)
识别纯文本语种Lang(doc *goquery.Document, charset string, listMode bool) LangRes
识别 HTML 语种
识别纯文本语种:
// 识别纯文本语种
lang, langPos := spider.LangText(text)
识别 HTML 语种:
// Http 请求获取响应
resp, err := spider.HttpGetResp(urlStr, req, timeout)
// 转换 goquery.*Document
doc, docErr := goquery.NewDocumentFromReader(bytes.NewReader(resp.Body))
// 根据字符集、页面类型返回
langRes := spider.Lang(doc, resp.Charset.Charset, false)
DetectDomain(domain string, timeout int, retry int) (*DomainRes, error)
探测主域名基本信息func DetectSubDomain(domain string, timeout int, retry int) (*DomainRes, error)
探测子域名基本信息
根据网站域名,尽可能的探测一些基本信息,基本信息包括:
type DomainRes struct {
// 域名
Domain string
// 主页域名
HomeDomain string
// 协议
Scheme string
// 字符集
Charset CharsetRes
// 语种
Lang LangRes
// 国家
Country string
// 省份
Province string
// 分类
Category string
// 标题
Title string
// 描述
Description string
// ICP
Icp string
// 状态
State bool
// 状态码
StatusCode int
// 内容页链接数量
ContentCount int
// 列表页链接数量
ListCount int
// 子域名列表
SubDomains map[string]bool
}
根据页面内容,自动分析识别并提取页面上的内容页、列表页以及其他链接,支持传入自定义规则干扰最终结果
分类依据通过链接标题、URL特征、以及统计归纳的方式
GetLinkData(urlStr string, strictDomain bool, timeout int, retry int) (*LinkData, error)
获取页面链接分类数据
type LinkData struct {
LinkRes *extract.LinkRes
// 过滤
Filters map[string]string
// 子域名
SubDomains map[string]bool
}
type LinkRes struct {
// 内容页
Content map[string]string
// 列表页
List map[string]string
// 未知链接
Unknown map[string]string
// 过滤链接
None map[string]string
}
新闻最重要的三要素:标题、发布时间、正文。其中发布时间对精准度要求高,标题和正文更追求完整性。
体验下来,业内最强大的是: diffbot 公司,猜测它可能是基于网页视觉+深度学习来实现。
有不少新闻正文提取或新闻正文抽取的开源的方案,大都是基于规则或统计方法实现。如:
- Python: GeneralNewsExtractor
- Java: WebCollector/ContentExtractor
更古老的还有:python-goose, newspaper,甚至 Readability、Html2Article 等等。
其中:WebCollector/ContentExtractor
是 基于标签路径特征融合新闻内容抽取的 CEPF 算法 的 Java 实现版本。
go-pkg-spider 实现了 CEPF 算法的 Golang 版本,在此基础上做了大量优化,内置了一些通用规则,更精细的控制了标题和发布时间的提取与转换,并支持多语种新闻网站的要素提取。
type News struct {
// 标题
Title string
// 标题提取依据
TitlePos string
// 发布时间
TimeLocal string
// 原始时间
Time string
// 发布时间时间提取依据
TimePos string
// 正文纯文本
Content string
// 正文 Node 节点
ContentNode *html.Node
// 提取用时(毫秒)
Spend int64
// 语种
Lang string
}
可根据 ContentNode *html.Node
来重新定义需要清洗保留的标签。
// Http 请求获取响应
resp, err := spider.HttpGetResp(urlStr, req, timeout)
// 转换 goquery.*Document
doc, docErr := goquery.NewDocumentFromReader(bytes.NewReader(resp.Body))
// 基本清理
doc.Find(spider.DefaultDocRemoveTags).Remove()
// 语种
langRes := Lang(doc, resp.Charset.Charset, false)
// 新闻提取
content := extract.NewContent(contentDoc, langRes.Lang, listTitle, urlStr)
// 新闻提取结果
news := content.ExtractNews()
可以通过下面的已经封装好的方法完成以上步骤:
GetNews(urlStr string, title string, timeout int, retry int) (*extract.News, *HttpResp, error)
获取链接新闻数据
本项目是一个数据提取工具库,不是爬虫框架或采集软件,只限于技术交流,源码中请求目标网站的相关代码仅为功能测试需要。
请在符合法律法规和相关规定的情况下使用本项目,禁止使用本项目进行任何非法、侵权或者违反公序良俗的行为。
使用本项目造成的直接或间接的风险由用户自行承担。