# -*- coding: utf-8 -*-
import pandas as pd
import requests
from goose3 import Goose
from goose3.text import StopWordsChinese, StopWordsKorean, StopWordsArabic
from base.smart.entity import *
from base.smart.smart_extractor_utility import SmartExtractorUtility
# goose3自带的lxml，提示找不到etree，但仍可使用
from lxml import etree
from lxml.html import HtmlElement


class SmartExtractor:
    @staticmethod
    def get_supported_lang_code_dict():
        """
        支持语言：
        1、需要分词，传递分词器（3种）：
           a. 中文、韩语、阿拉伯语
        2、不需要分词，直接传递语言编码（16种）
           a. 其中英语、俄语，单独测试
        """
        supported_lang_code_dict = {
            'cn': '中文',  # 中文
            'zh-cn': '简体中文',  # 简体中文
            'ko': '韩语',  # 韩语
            'ar': '阿拉伯语',  # 阿拉伯语
            'en': '英语',  # 英语
            'ru': '俄语',  # 俄语
            'da': '丹麦语',  # 丹麦语
            'de': '德语',  # 德语
            'es': '西班牙语',  # 西班牙语
            'fi': '芬兰语',  # 芬兰语
            'fr': '法语',  # 法语
            'hu': '匈牙利语',  # 匈牙利语
            'id': '印度尼西亚语',  # 印度尼西亚语
            'it': '意大利语',  # 意大利语
            'nb': '挪威语（伯克梅尔）',  # 挪威语（伯克梅尔）
            'nl': '荷兰语',  # 荷兰语
            'no': '挪威文（耐诺斯克）',  # 挪威文（耐诺斯克）
            'pl': '波兰语',  # 波兰语
            'pt': '葡萄牙语',  # 葡萄牙语
            'sv': '瑞典语',  # 瑞典语
        }

        return supported_lang_code_dict

    def __init__(self, lang_code='cn'):
        """
        构造器：未指定 lang_code 参数时，默认为 cn
        """
        # 支持语言
        supported_lang_code_list = list(SmartExtractor.get_supported_lang_code_dict())

        # 初始化 goose 对象：
        # 1、根据语言代码，创建 goose 对象
        if lang_code is None or lang_code == 'cn' or lang_code == 'zh-cn'or lang_code == 'zh':
            # 需要分词：中文
            # 1、不指定lang_code参数，或不指定lang_code为 None 时，默认为中文分词
            # 2、Flask Web接口：未指定get参数 lang_code 时，lang_code 会接收为 None
            self.goose = Goose({'stopwords_class': StopWordsChinese})
        elif lang_code == 'ko':
            # 需要分词：韩语
            # 1、测试：只传递语言，不传递分词器
            # self.goose = Goose({'use_meta_language': False, 'target_language': 'ko'})  # 测试失败：正文采集为空
            # self.goose = Goose()    # 测试失败：正文采集为空
            # 韩语分词：测试成功
            self.goose = Goose({'stopwords_class': StopWordsKorean})
        elif lang_code == 'ar':
            # 需要分词：阿拉伯语
            # self.goose = Goose({'use_meta_language': False, 'target_language': 'en'})       # 测试失败：正文采集为空
            # self.goose = Goose()    # 测试成功
            # self.goose = Goose({'use_meta_language': False, 'target_language': lang_code})  # 测试成功：直接传递语言编码
            self.goose = Goose({'stopwords_class': StopWordsArabic})
        elif lang_code == 'en':
            # 单独测试：英文
            # self.goose = Goose({'use_meta_language': False, 'target_language': 'en'})
            # 测试成功：创建Goose对象时，不指定语言默认为英文分词
            self.goose = Goose()
        elif lang_code == 'ru':
            # 单独测试：俄语
            # self.goose = Goose({'use_meta_language': False, 'target_language': 'en'})       # 测试失败：正文采集为空
            self.goose = Goose({'use_meta_language': False, 'target_language': lang_code})  # 测试成功：直接传递语言编码
        elif lang_code in supported_lang_code_list:
            # 其它语言编码，统一处理，不再单独测试
            self.goose = Goose({'use_meta_language': False, 'target_language': lang_code})
        else:
            # 未识别的语言代码
            raise Exception(f'智能采集时，无法识别语言代码：{lang_code}')

    def get_extraction_result(self, article, link_text=''):
        """
        获取采集结果：
        1、从 artcile 对象中，采集数据并封装到 ExtractionResult
        """
        # 用于保存：采集后的文本
        extraction_result = ExtractionResult()

        # 标题
        # extraction_result.title = article.title     # 原办法：使用 goose 采集到的 title 中的标题
        extraction_result.title = SmartExtractorUtility.get_article_title(article, link_text)
        # 发布日期
        extraction_result.publish_date = SmartExtractorUtility.get_publish_date(article)
        # 正文（保留所有HTML标记，如：br、img）
        extraction_result.text = SmartExtractorUtility.get_article_text(article)
        # URL
        extraction_result.url = article.final_url

        # 摘要
        extraction_result.meta_description = article.meta_description
        # 干净正文（不带HTML）
        extraction_result.cleaned_text = article.cleaned_text
        # 来源（目前只支持采集中文网站中的“来源”）
        extraction_result.source = ''

        return extraction_result



    def getContentByUrl(self, url):
        """
        按URL采集内容
        """
        # 采集正文：传入url
        article = self.goose.extract(url=url)
        return article.cleaned_text

    def extract_by_url(self, url, link_text=''):
        """
        按URL采集内容
        """
        # 采集正文：传入url
        article = self.goose.extract(url=url)
        # article = goose.extract(raw_html=html)

        return self.get_extraction_result(article, link_text)

#url_list = [["搜狐新闻",'https://news.tianyancha.com/ll_uc76l7d774.html?gid=1499023','430418'],.....]
def extract_by_url_test(url_list,list_info_all):
    # 测试：按URL采集
    # url_list = [
    #     # "http://www.news.cn/politics/2022-07/31/c_1128879636.htm",  # 短文本
    #     # "https://baijiahao.baidu.com/s?id=1741311527693101670",  # 带多张图片
    #     # "https://news.cctv.com/2022/08/16/ARTIERrXbbVtVUaQU0pMzQxf220816.shtml",  # 带多张图片，及一个视频（测试内容XPath失败）
    #     # "http://opinion.people.com.cn/n1/2022/0803/c1003-32492653.html",  # 人民网
    #     # 韩文：中央日报-politics
    #     # "https://www.joongang.co.kr/article/25094974",
    #     # "https://www.joongang.co.kr/article/25094967",
    #     # 英文：加德满都邮报-national-security
    #     # "https://kathmandupost.com/national-security/2020/01/17/police-s-intelligence-continues-to-fail-them-as-chand-party-claims-explosion",
    #     # "https://kathmandupost.com/national-security/2019/11/04/india-s-new-political-map-places-disputed-territory-of-kalapani-inside-its-own-borders",  # 测试采集：发布时间
    #     # 俄语：今日白俄罗斯报-word
    #     # "https://www.sb.by/articles/byvshiy-premer-ministr-italii-zayavil-chto-strane-sleduet-otkazatsya-ot-gaza-iz-rossii.html",
    #     # 'https://www.sb.by/articles/kryuchkov-predupredil-o-nepopravimykh-posledstviyakh-dlya-ukrainy-v-sluchae-udarov-po-krymu.html',
    #     # 阿语
    #     # "http://arabic.people.com.cn/n3/2022/0822/c31659-10137917.html",
    #     # "http://arabic.people.com.cn/n3/2022/0822/c31657-10137909.html",
    #     # 测试提取标题
    #     # "http://www.sasac.gov.cn/n4470048/n16518962/n20928507/n20928570/c25819031/content.html",
    #     # "http://www.forestry.gov.cn/main/102/20220823/092407820617754.html",
    #     # "http://www.sasac.gov.cn/n2588025/n2588139/c25825832/content.html", # 标题采集为空
    #     # 'http://www.crfeb.com.cn/1j/_124/2005409/index.html',   # 内容采集失败
    #     # 'http://www.crfeb.com.cn/1j/_124/912248/index.html',  # 内容采集失败
    #     # 'https://www.crcc.cn/art/2021/11/12/art_205_3413380.html',  # 中国铁建股份有限公司-工作动态（日期采集错误）
    #     # 'http://ccecc.crcc.cn/art/2015/11/19/art_7608_1136312.html',  # 中国土木工程集团有限公司-多个栏目（日期采集错误）
    #     # 'http://v.people.cn/n1/2022/0901/c444662-32517559.html',    # 人民网视频：title必须以“元素中的标题”开始，不能判断“包含”
    #     # 'https://www.chec.bj.cn/cn/xwzx/gsyw/2022/202207/t20220706_8128.html', # 中国港湾工程有限责任公司-公司要闻（标题采集失败）
    #     # 'https://www.cscec.com/xwzx_new/gsyw_new/202208/3570377.html', # 中国建筑集团有限公司-中建要闻（标题采集失败）
    #     # 'https://www.crbc.com/site/crbc/276/info/2022/46884837.html',  # 中国路桥工程有限责任公司-多个栏目（标题采集失败）
    #     # 'http://www.cgcoc.com.cn/news/432.html',  # 中地海外集团有限公司-新闻中心（标题和内容采集失败）
    #     # 'http://www.mcc.com.cn/mcc/_132154/_132572/308233/index.html'  # 中国五矿（测试：正文采集失败）
    #     # 'http://www.powerchina.cn/art/2015/5/27/art_7449_441845.html',  # 中国电力建设集团（测试：标题、正文采集失败）
    #     # 中国电力建设集团（测试：标题采集失败），相比列表中的链接文本、title标签中的内容，元素中的标题，“秉承丝路精髓  抒写锦绣华章”中间多出一个空格
    #     # 'http://world.people.com.cn/n1/2022/0624/c1002-32455607.html',  # 标题采集失败：看着没有问题
    #     # 'https://www.cscec.com/xwzx_new/zqydt_new/202209/3578274.html',  # 中国建筑股份有限公司-企业动态：日期采集错误，采集到当天日期
    #     'https://3g.k.sohu.com/t/n705260979'    #天眼查--企业公告'
    # ]

    # 语言编码
    lang_code = 'cn'
    # lang_code = 'ko'
    # lang_code = 'en'
    # lang_code = 'ru'
    # lang_code = 'ar'

    #url = ["搜狐新闻",'https://news.tianyancha.com/ll_uc76l7d774.html?gid=1499023','430418']
    for url in url_list:
        #当前企业公告中的一条信息
        print()
        print("-" * 100)
        print('请求URL：', url[1])
        extraction_result = SmartExtractor(lang_code).extract_by_url(url[1])

        # 测试转换为JSON
        # 1、直接转换时，会抛异常：TypeError: Object of type ExtractionResult is not JSON serializable
        # print(json.dumps(extraction_result))
        # print(json.dumps(extraction_result, default=ExtractionResult.to_dict))    # 转换成功：指定序列化器
        # print(type(json.dumps(extraction_result.to_dict())))  # 返回类型：<class 'str'>，内容中的中文会被转义
        # print(str(extraction_result.to_dict()))     # 如果直接转换为字符串，中文不会被转义
        # 当前企业数据拿完
        list_info = [
            extraction_result.title,
            extraction_result.publish_date,
            extraction_result.cleaned_text,
            extraction_result.url,
            url[0],
            url[2],
            '天眼查',
        ]
    return list_info
