技术文章:谷歌翻译软件实现网站内容自动翻译更新
优采云 发布时间: 2022-10-06 08:18技术文章:谷歌翻译软件实现网站内容自动翻译更新
谷歌翻译软件在线提供中英文翻译和其他语言的翻译。通过谷歌翻译软件,我们可以将需要的文档批量翻译成其他语言和文本,并可以进行简体中文和繁体中文的交换,如图,我们不仅可以在谷歌翻译软件上实现文本翻译,还可以批量编辑已翻译文本的 伪原创。
全自动谷歌翻译软件广泛应用于我们的谷歌网站建设和自媒体网站建设等。通过全自动谷歌翻译软件,我们可以轻松完成从内容材料的全网采集,批量本地翻译编辑和一键发布网站自媒体平台实现文章的自动更新。
谷歌翻译软件有网站内容更新和网站链接建设,可以让我们全方位提升网站的排名和质量。并非所有链接都有用。我们需要信誉良好的 网站 的链接。糟糕的链接构建做法会受到 Google 的惩罚,并可能产生相反的效果,降低我们的 网站 结果。这绝对是一场质量胜于数量的游戏。
如果我们不确定该怎么做,最好的开始方法是避免以任何方式购买链接。另外,不要从 网站 获取与我们的利基和产品无关的链接。如果我们在网上做生意,我们很可能听说过 Google Plugins(Google 翻译软件)。如果没有,现在可能是学习的时候了!谷歌翻译软件是一种转型工具,它告诉我们我们需要了解的关于我们的受众的所有信息等等。
多亏了 Google 翻译软件,我们不再需要依靠基本的市场调查来找出我们的 网站 受众是谁。使用数据,我们可以直接观察我们的受众。这包括他们的人口统计、兴趣和位置等信息。但谷歌翻译软件不只是告诉我们的听众。这个软件在很多方面帮助我们改进网站。特别是一个领域是搜索引擎优化。
公平地说,谷歌翻译软件多年来发生了很大变化。有很多次迭代,每次都在最后一次改进。Google 插件是具有全新数据模型的开创性更新。Google 插件有很多好处,包括更好地跟踪移动应用程序以及与 BigQuery 的免费集成。如果我们开始使用谷歌翻译软件,那么这就是我们应该选择的版本。
跟踪关键字,我们已经解释了关键字对 SEO 的重要性。但是让您的关键字保持最新可能会很棘手。人们的搜索习惯会发生变化,最流行的关键词也会发生变化。幸运的是,谷歌翻译软件大大简化了这个过程。
这是因为谷歌翻译软件为我们提供了关键词报告。这是一份方便的文档,详细介绍了我们的 网站 上最流行的关键字。这包括每个关键字的展示次数和平均点击率。
谷歌翻译软件实现了文章相关性和原创相关性的提升,网站和在自媒体SEO中,对原创、时效性、流行相关性的重视可以借助谷歌翻译软件。
免费获取:源码剖析 - 公众号采集阅读器 Liuli
介绍
偶然发现了琉璃这个项目,项目Github:
看了它的文章,发现琉璃是用Python实现的,所以打算简单看一下它的实现细节,老规矩,看项目,先把好奇的点写下来:
是的,我对这两点很感兴趣。经过一番阅读,关于好奇心 1、其实没有人实现过漂亮的PC软件界面。琉璃只是采集,然后推送内容,所以这篇文章的重点,就看怎么了采集公众号文章,另外,在阅读的过程中,我发现LiuLi还用了一个简单的方法来识别文章是不是广告文章,这个也很有意思,也记录一下。
公众号文章采集
琉璃基于搜狗微信()对公众号文章进行采集,实现了两种方法:
我们可以通过相应的配置文件来控制琉璃使用哪种方式执行文章采集,它使用ruia默认的方式执行采集。
琉璃将功能划分为多个模块,然后通过调度器调度不同的模块。调度器启动方法代码如下:
# src/liuli_schedule.py<br /><br />def start(ll_config_name: str = ""):<br /> """调度启动函数<br /><br /> Args:<br /> task_config (dict): 调度任务配置<br /> """<br /> if not ll_config_name:<br /> freeze_support()<br /><br /> # 默认启动 liuli_config 目录下所有配置<br /> ll_config_name_list = []<br /> for each_file in os.listdir(Config.LL_CONFIG_DIR):<br /> if each_file.endswith("json"):<br /> # 加入启动列表<br /> ll_config_name_list.append(each_file.replace(".json", ""))<br /> # 进程池<br /> p = Pool(len(ll_config_name_list))<br /> for each_ll_config_name in ll_config_name_list:<br /> LOGGER.info(f"Task {each_ll_config_name} register successfully!")<br /> p.apply_async(run_liuli_schedule, args=(each_ll_config_name,))<br /> p.close()<br /> p.join()<br /><br /> else:<br /> run_liuli_schedule(ll_config_name)<br />
从代码中可以看出,调度器会启动Python进程池,然后在其中添加run_liuli_schedule异步任务。在这个异步任务中,会执行run_liuli_task方法,这是一个完整的任务流程。代码如下:
def run_liuli_task(ll_config: dict):<br /> """执行调度任务<br /><br /> Args:<br /> ll_config (dict): Liuli 任务配置<br /> """<br /> # 文章源, 用于基础查询条件<br /> doc_source: str = ll_config["doc_source"]<br /> basic_filter = {"basic_filter": {"doc_source": doc_source}}<br /> # 采集器配置<br /> collector_conf: dict = ll_config["collector"]<br /> # 处理器配置<br /> processor_conf: dict = ll_config["processor"]<br /> # 分发器配置<br /> sender_conf: dict = ll_config["sender"]<br /> sender_conf.update(basic_filter)<br /> # 备份器配置<br /> backup_conf: dict = ll_config["backup"]<br /> backup_conf.update(basic_filter)<br /><br /> # 采集器执行<br /> LOGGER.info("采集器开始执行!")<br /> for collect_type, collect_config in collector_conf.items():<br /> collect_factory(collect_type, collect_config)<br /> LOGGER.info("采集器执行完毕!")<br /> # 采集器执行<br /> LOGGER.info("处理器(after_collect): 开始执行!")<br /> for each in processor_conf["after_collect"]:<br /> func_name = each.pop("func")<br /> # 注入查询条件<br /> each.update(basic_filter)<br /> LOGGER.info(f"处理器(after_collect): {func_name} 正在执行...")<br /> processor_dict[func_name](**each)<br /> LOGGER.info("处理器(after_collect): 执行完毕!")<br /> # 分发器执行<br /> LOGGER.info("分发器开始执行!")<br /> send_doc(sender_conf)<br /> LOGGER.info("分发器执行完毕!")<br /> # 备份器执行<br /> LOGGER.info("备份器开始执行!")<br /> backup_doc(backup_conf)<br /> LOGGER.info("备份器执行完毕!")<br />
从 run_liuli_task 方法中,需要执行一个 Liuli 任务:
关于琉璃的功能大家可以阅读作者自己的文章:,这里我们只关注公众号采集的逻辑。
因为ruia和playwright实现的采集器有两种不同的方式,使用哪一种由配置文件决定,然后通过import_module方法动态导入对应的模块,然后运行模块的run方法,从而实现文章的公众号采集,相关代码如下:
def collect_factory(collect_type: str, collect_config: dict) -> bool:<br /> """<br /> 采集器工厂函数<br /> :param collect_type: 采集器类型<br /> :param collect_config: 采集器配置<br /> :return:<br /> """<br /> collect_status = False<br /> try:<br /> # import_module方法动态载入具体的采集模块<br /> collect_module = import_module(f"src.collector.{collect_type}")<br /> collect_status = collect_module.run(collect_config)<br /> except ModuleNotFoundError:<br /> LOGGER.error(f"采集器类型不存在 {collect_type} - {collect_config}")<br /> except Exception as e:<br /> LOGGER.error(f"采集器执行出错 {collect_type} - {collect_config} - {e}")<br /> return collect_status<br />
编剧采集模块实现
Playwright 是微软出品的自动化库。它类似于硒。它定位于网页测试,但也被人们用来获取网页信息。当然,一些前端的反爬措施,编剧是无法突破的。
与selenium相比,playwright支持python的async,性能有所提升(但还是比不上直接请求)。下面是获取公众号下最新文章的一些逻辑(完整代码太长):
async def playwright_main(wechat_name: str):<br /> """利用 playwright 获取公众号元信息,输出数据格式见上方<br /> Args:<br /> wechat_name ([str]): 公众号名称<br /> """<br /> wechat_data = {}<br /> try:<br /> async with async_playwright() as p:<br /> # browser = await p.chromium.launch(headless=False)<br /> browser = await p.chromium.launch()<br /> context = await browser.new_context(user_agent=Config.SPIDER_UA)<br /> page = await context.new_page()<br /> # 进行公众号检索<br /> await page.goto("https://weixin.sogou.com/")<br /> await page.wait_for_load_state()<br /> await page.click('input[name="query"]')<br /> await page.fill('input[name="query"]', wechat_name)<br /> await asyncio.sleep(1)<br /> await page.click("text=搜公众号")<br /> await page.wait_for_load_state()<br />
从上面的代码可以看出,playwright的用法和selenium很相似,通过自动化用户操作网站的过程可以得到对应的数据。
ruia 采集 模块实现
ruia 是一个轻量级的 Python 异步爬虫框架。因为它比较轻量级,所以我也把它的代码看成了下一篇文章文章的内容。
它的用法有点像scrapy。需要定义一个继承自ruia.Spider的子类,然后调用start方法请求目标网站,然后ruia会自动调用parse方法解析网页内容。我们来看看具体的代码,首先是入口逻辑:
def run(collect_config: dict):<br /> """微信公众号文章抓取爬虫<br /><br /> Args:<br /> collect_config (dict, optional): 采集器配置<br /> """<br /> s_nums = 0<br /> wechat_list = collect_config["wechat_list"]<br /> delta_time = collect_config.get("delta_time", 5)<br /> for wechat_name in wechat_list:<br /> SGWechatSpider.wechat_name = wechat_name<br /> SGWechatSpider.request_config = {<br /> "RETRIES": 3,<br /> "DELAY": delta_time,<br /> "TIMEOUT": 20,<br /> }<br /> sg_url = f"https://weixin.sogou.com/weixin?type=1&query={wechat_name}&ie=utf8&s_from=input&_sug_=n&_sug_type_="<br /> SGWechatSpider.start_urls = [sg_url]<br /> try:<br /> # 启动爬虫<br /> SGWechatSpider.start(middleware=ua_middleware)<br /> s_nums += 1<br /> except Exception as e:<br /> err_msg = f" 公众号->{wechat_name} 文章更新失败! 错误信息: {e}"<br /> LOGGER.error(err_msg)<br /><br /> msg = f" 微信公众号文章更新完毕({s_nums}/{len(wechat_list)})!"<br /> LOGGER.info(msg)<br />
上面代码中,爬虫是通过SGWechatSpider.start(middleware=ua_middleware)启动的,它会自动请求start_urls的url,然后回调parse方法。parse方法的代码如下:
async def parse(self, response: Response):<br /> """解析公众号原始链接数据"""<br /> html = await response.text()<br /> item_list = []<br /> async for item in SGWechatItem.get_items(html=html):<br /> if item.wechat_name == self.wechat_name:<br /> item_list.append(item)<br /> yield self.request(<br /> url=item.latest_href,<br /> metadata=item.results,<br /> # 下一个回调方法<br /> callback=self.parse_real_wechat_url,<br /> )<br /> break<br />
在parse方法中,通过self.request请求一个新的url,然后回调self.parse_real_wechat_url方法。一切都与scrapy如此相似。
至此采集模块的阅读就结束了(代码中还涉及到一些简单的数据清洗,本文不做讨论),没有特别复杂的部分,从代码来看,作者没被派去做反爬逻辑处理,搜狗微信没反爬?
广告文章标识
然后看广告文章的识别,琉璃还是会采集为广告文章,经过采集,在文章处理模块中,广告文章标记出来,先分析广告文章标记的入口逻辑,回到liuli_schedule.py的run_lili_task方法,注意进程的逻辑(文章处理模块) ,代码如下:
LOGGER.info("处理器(after_collect): 开始执行!")<br /> for each in processor_conf["after_collect"]:<br /> func_name = each.pop("func")<br /> # 注入查询条件<br /> each.update(basic_filter)<br /> LOGGER.info(f"处理器(after_collect): {func_name} 正在执行...")<br /> processor_dict[func_name](**each)<br /> LOGGER.info("处理器(after_collect): 执行完毕!")<br />
从上面的代码可以看出,处理器的主要逻辑是processor_dict字典中的方法。字典的定义路径是 src/processor/__init__.py。代码如下:
from .rss_utils import to_rss<br />from .text_utils import (<br /> ad_marker,<br /> extract_core_html,<br /> extract_keyword_list,<br /> html_to_text_h2t,<br /> str_replace,<br />)<br /><br />processor_dict = {<br /> "to_rss": to_rss,<br /> "ad_marker": ad_marker,<br /> "str_replace": str_replace,<br />}<br />
ad_marker 方法是一种识别文章 是否是广告文章 的方法。其实写的有点绕。核心逻辑是计算当前文章和采集到广告文章构造词频向量的余弦值,判断余弦值的大小判断是否为广告文章,简单看一下相关逻辑。
在ad_marker方法中会调用model_predict_factory方法,传入当前文章的标题、文章的内容和分类的cos_value。相关代码如下(已清理上代码,只显示所需的部分):
def ad_marker(<br /> cos_value: float = 0.6,<br /> is_force=False,<br /> basic_filter={},<br /> **kwargs,<br />):<br /> # 基于余弦相似度<br /> cos_model_resp = model_predict_factory(<br /> model_name="cos",<br /> model_path="",<br /> input_dict={"text": doc_name + doc_keywords, "cos_value": cos_value},<br /> # input_dict={"text": doc_name, "cos_value": Config.COS_VALUE},<br /> ).to_dict()<br />
cos_value为0.6,即如果计算出当前文章与广告文章的余弦值大于等于0.6,则认为当前文章为广告文章,其最终预测逻辑在classifier/model_base/cos_model_loader.py的predict方法中,代码如下:
def predict(self, text: str, cos_value: float = 0.8) -> dict:<br /> """<br /> 对文本相似度进行预测<br /> :param text: 文本<br /> :param cos_value: 阈值 默认是0.9<br /> :return:<br /> """<br /> max_pro, result = 0.0, 0<br /> for each in self.train_data:<br /> # 余弦值具体的运算逻辑<br /> cos = CosineSimilarity(self.process_text(text), each)<br /> res_dict = cos.calculate()<br /> value = res_dict["value"]<br /> # 大于等于cos_value,就返回1,则表示当前的文章是广告文章<br /> result = 1 if value >= cos_value else 0<br /> max_pro = value if value > max_pro else max_pro<br /> if result == 1:<br /> break<br /><br /> return {"result": result, "value": max_pro}<br />
余弦值的具体操作逻辑在CosineSimilarity的calculate方法中,都是和数学有关的,我就不看了。核心是判断当前文章与广告文章的相似度。可以通过TFIDF、文本聚类等算法来完成,相关库几行代码就可以搞定(所以感觉就写在这里)。
剩下的可以参考逻辑结束
琉璃是一个不错的学习项目,下一部分文章,一起来学习ruia Python轻量级异步爬虫框架的代码。