Files
2021-10-01 13:30:26 +08:00

296 lines
13 KiB
Python

import concurrent.futures
import configparser
import json
import logging
import traceback
from typing import List
from spider.baidu_spider import BaiduSpider
from spider.wikipedia_spider import WikiSpider
from util import generate_wiki_file_list
military_list_of_lists_url_list_en = [
"https://en.wikipedia.org/wiki/Lists_of_accidents_and_incidents_involving_military_aircraft",
"https://en.wikipedia.org/wiki/Lists_of_armoured_fighting_vehicles",
"https://en.wikipedia.org/wiki/List_of_artillery", "https://en.wikipedia.org/wiki/Lists_of_gun_cartridges",
"https://en.wikipedia.org/wiki/Lists_of_military_aircraft_by_nation",
"https://en.wikipedia.org/wiki/Lists_of_Bulgarian_military_aircraft",
"https://en.wikipedia.org/wiki/Lists_of_military_equipment",
"https://en.wikipedia.org/wiki/Lists_of_currently_active_military_equipment_by_country",
"https://en.wikipedia.org/wiki/Lists_of_military_installations",
"https://en.wikipedia.org/wiki/Lists_of_naval_flags", "https://en.wikipedia.org/wiki/Lists_of_swords",
"https://en.wikipedia.org/wiki/Lists_of_weapons",
"https://en.wikipedia.org/wiki/Lists_of_World_War_II_military_equipment",
]
military_list_of_lists_url_list_jp = [
"https://ja.wikipedia.org/wiki/%E8%BB%8D%E4%BA%8B%E5%AD%A6%E8%80%85",
"https://ja.wikipedia.org/wiki/%E8%BB%8D%E4%BA%8B%E7%95%A5%E8%AA%9E%E4%B8%80%E8%A6%A7",
"https://ja.wikipedia.org/wiki/%E8%BB%8D%E9%9A%8A%E3%81%AE%E9%9A%8E%E7%B4%9A",
"https://ja.wikipedia.org/wiki/%E5%90%84%E5%9B%BD%E3%81%AE%E8%BB%8D%E9%9A%8A%E3%81%AE%E4%B8%80%E8%A6%A7",
"https://ja.wikipedia.org/wiki/%E9%99%B8%E8%BB%8D%E3%81%AE%E4%B8%80%E8%A6%A7",
"https://ja.wikipedia.org/wiki/%E6%B5%B7%E8%BB%8D%E3%81%AE%E4%B8%80%E8%A6%A7",
"https://ja.wikipedia.org/wiki/%E7%A9%BA%E8%BB%8D%E3%81%AE%E4%B8%80%E8%A6%A7",
"https://ja.wikipedia.org/wiki/%E6%AD%B4%E5%8F%B2%E4%B8%8A%E3%81%AE%E8%BB%8D%E9%9A%8A%E3%81%AE%E4%B8%80%E8%A6%A7",
"https://ja.wikipedia.org/wiki/%E7%A9%BA%E8%BB%8D%E5%9F%BA%E5%9C%B0%E3%81%AE%E4%B8%80%E8%A6%A7",
"https://ja.wikipedia.org/wiki/%E3%82%A2%E3%83%A1%E3%83%AA%E3%82%AB%E7%A9%BA%E8%BB%8D%E5%9F%BA%E5%9C%B0%E3%81%AE%E4%B8%80%E8%A6%A7",
"https://ja.wikipedia.org/wiki/%E7%89%B9%E6%AE%8A%E9%83%A8%E9%9A%8A%E3%81%AE%E4%B8%80%E8%A6%A7",
"https://ja.wikipedia.org/wiki/%E9%99%B8%E4%B8%8A%E8%87%AA%E8%A1%9B%E9%9A%8A%E3%81%AE%E9%A7%90%E5%B1%AF%E5%9C%B0%E4%B8%80%E8%A6%A7",
"https://ja.wikipedia.org/wiki/%E6%B5%B7%E4%B8%8A%E8%87%AA%E8%A1%9B%E9%9A%8A%E3%81%AE%E9%99%B8%E4%B8%8A%E6%96%BD%E8%A8%AD%E4%B8%80%E8%A6%A7",
"https://ja.wikipedia.org/wiki/%E8%88%AA%E7%A9%BA%E8%87%AA%E8%A1%9B%E9%9A%8A%E3%81%AE%E5%9F%BA%E5%9C%B0%E4%B8%80%E8%A6%A7",
"https://ja.wikipedia.org/wiki/%E8%BB%8D%E9%9A%8A%E3%82%92%E4%BF%9D%E6%9C%89%E3%81%97%E3%81%A6%E3%81%84%E3%81%AA%E3%81%84%E5%9B%BD%E5%AE%B6%E3%81%AE%E4%B8%80%E8%A6%A7",
"https://ja.wikipedia.org/wiki/%E9%98%B2%E8%A1%9B%E4%B8%8D%E7%A5%A5%E4%BA%8B#%E4%B8%BB%E3%81%AA%E4%B8%8D%E7%A5%A5%E4%BA%8B",
"https://ja.wikipedia.org/wiki/%E8%BB%8D%E5%AD%A6%E8%80%85",
"https://ja.wikipedia.org/wiki/%E6%88%A6%E4%BA%89%E4%B8%80%E8%A6%A7",
"https://ja.wikipedia.org/wiki/%E6%88%A6%E9%97%98%E4%B8%80%E8%A6%A7",
]
# wrapper函数是为了在concurrent中多线程调用
def get_web_content_wrapper(wiki_spider: WikiSpider, url: str, loggers: logging.Logger, is_from_file=False):
try:
return wiki_spider.get_web_content(url, is_from_file=is_from_file)
except Exception as e:
loggers.warning("failed to get content: {}, err:{}".format(url, e))
traceback.print_exc()
return None
def get_extra_links_wrapper(wiki_spider: BaiduSpider, url: str, loggers: logging.Logger, is_from_file=False):
try:
return wiki_spider.get_extra_links(url, is_from_file)
except Exception as e:
loggers.warning("failed to get extra links: {}".format(url))
return None
def get_extra_links(configure, url_list_file, output_file, max_iter_times=30, is_from_file=False):
logging.basicConfig(filename='spider.log', format="%(asctime)s %(filename)s : %(levelname)s %(message)s",
datefmt='%Y-%m-%d: %H:%M:%S',
level=logging.DEBUG)
logger = logging.getLogger(__name__)
logger.setLevel(logging.DEBUG)
url_list = set()
s = BaiduSpider(configure)
with open(url_list_file, "r", encoding='utf-8') as f:
for line in f:
url_list.add(line[:-1])
logger.info("spider start")
new_links = set()
new_new_links = set()
with concurrent.futures.ThreadPoolExecutor() as executor:
futures = [executor.submit(get_extra_links_wrapper, s, url, logger, is_from_file) for url in url_list]
for future in concurrent.futures.as_completed(futures):
r = future.result()
if r is not None:
extra_links_set = set(r)
new_links |= extra_links_set - set(url_list)
url_list |= new_links
for i in range(max_iter_times):
print("iter: {}".format(i))
with concurrent.futures.ThreadPoolExecutor() as executor:
futures = [executor.submit(get_extra_links_wrapper, s, url, logger, is_from_file) for url in new_links]
for future in concurrent.futures.as_completed(futures):
r = future.result()
if r is not None:
extra_links_set = set(r)
new_new_links |= extra_links_set - set(new_links)
if len(new_new_links) == 0:
break
url_list |= new_new_links
print("new links: {}".format(len(new_new_links)))
new_links = new_new_links
with open(output_file, "w", encoding="utf-8") as f:
for url in url_list:
f.write(url + "\n")
def get_web_content_json(configure, language, url_list_file, output_file, is_from_file=False):
logging.basicConfig(filename='spider.log', format="%(asctime)s %(filename)s : %(levelname)s %(message)s",
datefmt='%Y-%m-%d: %H:%M:%S',
level=logging.DEBUG)
logger = logging.getLogger(__name__)
logger.setLevel(logging.DEBUG)
# s = WikiSpider(configure, language)
s = BaiduSpider(configure)
url_list = []
with open(url_list_file, "r", encoding='utf-8') as f:
for line in f:
url_list.append(line[:-1])
result_list = []
logger.info("spider start")
with concurrent.futures.ThreadPoolExecutor() as executor:
futures = [executor.submit(get_web_content_wrapper, s, url, logger, is_from_file) for url in url_list]
for future in concurrent.futures.as_completed(futures):
r = future.result()
if r is not None:
result_list.append(r)
logger.info("spider finished")
logger.info("writing result to file: {}".format(output_file))
with open(output_file, 'w', encoding='utf-8') as f:
for result in result_list:
j = json.dumps(result, ensure_ascii=False)
f.write(j + '\n')
logger.info("writing finished")
logger.info("{} line writen".format(len(result_list)))
def get_web_list(configure, list_of_list_url_list, language, output_path):
logging.basicConfig(filename='spider.log', format="%(asctime)s %(filename)s : %(levelname)s %(message)s",
datefmt='%Y-%m-%d: %H:%M:%S',
level=logging.DEBUG)
logger = logging.getLogger(__name__)
logger.setLevel(logging.DEBUG)
s = WikiSpider(configure, language)
# for idx, url in enumerate(url_list):
# s.get_web_content(url)
# if idx % 10 == 0:
# logger.debug("{} urls processed".format(idx))
# # print(idx)
link_set = set()
try:
for list_url in list_of_list_url_list:
list_list = s.get_lists(list_url)
for list_page in list_list:
new_url = s.get_links_from_list(list_page)
link_set |= new_url
except Exception as e:
with open(output_path, "w", encoding="utf-8") as f:
for u in link_set:
f.write(u + "\n")
print(e)
else:
with open(output_path, "w", encoding="utf-8") as f:
for u in link_set:
f.write(u + "\n")
print(len(link_set))
def test_baidu(config):
"""
一个单纯用来测试的函数
:param config:
"""
s = BaiduSpider(config)
r = s.get_web_content("https://baike.baidu.com/item/%E6%AD%BC-20")
j = json.dumps(r, ensure_ascii=False)
with open("test.txt", "w", encoding="utf-8") as f:
f.write(j + "\n")
# print(s.get_web_content("https://baike.baidu.com/item/%E6%AD%BC-20"))
# wrapper函数是为了在concurrent中多线程调用
def get_align_web_content_wrapper(wiki_spider_zh: WikiSpider, wiki_spider_tgt: WikiSpider, url_zh: str, url_tgt: str,
tgt_name: str,
is_from_file=False):
try:
url_zh = url_zh.replace('/wiki/', '/zh-cn/')
content_zh = wiki_spider_zh.get_web_content(url_zh, is_from_file=is_from_file)
content_tgt = wiki_spider_tgt.get_web_content(url_tgt, is_from_file=is_from_file)
return {'url': url_zh, 'chinese': content_zh, tgt_name: content_tgt}
except Exception as e:
traceback.print_exc()
return None
def get_align_item(configure, align_url_file: str):
with open(align_url_file, 'r', encoding='utf-8') as f:
content = f.read()
json_obj = json.loads(content)
s_zh = WikiSpider(configure, 'zh')
s_ja = WikiSpider(configure, 'ja')
result_list = []
with concurrent.futures.ThreadPoolExecutor() as executor:
futures = [executor.submit(get_align_web_content_wrapper, s_zh, s_ja, url_pair['中文'], url_pair['日本語'], 'ja')
for
url_pair
in json_obj]
for future in concurrent.futures.as_completed(futures):
r = future.result()
if r is not None:
result_list.append(r)
with open('data/zh-ja-item-simplified.txt', 'w', encoding='utf-8') as f:
f.write(json.dumps(result_list, ensure_ascii=False))
def get_pic_wrapper(spider: BaiduSpider, item: List):
try:
item_id = item[0]
item_name = item[1]
baike_url = ''
for url in item[2:]:
if 'baike.baidu.com' in url:
baike_url = url
break
item_info = spider.get_web_content(baike_url)
for v in item_info.values():
item.append(v['imgs'])
return item
except:
return item.append([])
def get_pic(configure, url_file: str):
with open(url_file, 'r', encoding='utf-8') as f:
content = f.read()
json_obj = json.loads(content)
# json_obj = json_obj[0:10]
s = BaiduSpider(configure)
result_list = []
# get_pic_wrapper(s, json_obj)
with concurrent.futures.ThreadPoolExecutor() as executor:
futures = [executor.submit(get_pic_wrapper, s, item) for item in json_obj]
for future in concurrent.futures.as_completed(futures):
r = future.result()
result_list.append(r)
with open('data/eid_url_with_pic.txt', 'w', encoding='utf-8') as f:
f.write(json.dumps(result_list, ensure_ascii=False))
if __name__ == '__main__':
# url_list = []
# 一些配置信息写在了config.ini中,主要是爬Wikipedia时用到的proxy信息
config = configparser.ConfigParser()
config.read("config.ini")
# get_web_list(config, military_list_of_lists_url_list_jp, "ja", "data/ja_wiki_urls.txt")
# get_web_content_json(config, 'zh', "data/baidu_baike_urls_extra.txt",
# "data/baidu_baike_data_with_summary_extra.txt",
# is_from_file=False)
# s = BaiduSpider(config)
# entity_name = s.check_entity_name('mq-9')
# print(entity_name)
# r = s.get_extra_links("https://baike.baidu.com/item/%E6%AD%BC-20")
# print(r)
# get_extra_links(config, "data/baidu_baike_urls.txt", "data/baidu_baike_urls_extra.txt")
# test_baidu(config)
# s = WikiSpider(config, 'en')
# s.align_language('data/ja_wiki_urls.txt', '日本語', '中文')
# s.align_chinese('data/title.txt')
# get_align_item(config, 'data/日本語-中文-align-urls.txt')
# get_pic(config, 'data/eid_url.txt')
s = WikiSpider(config, 'zh')
path_list = generate_wiki_file_list()
result_list = []
for path in path_list:
try:
result_list.append(s.get_web_content(path, True))
except:
continue
json_obj = json.dumps(result_list, ensure_ascii=False)
with open('data/wiki_page_url_tmp.json','w', encoding='utf-8') as f:
f.write(json_obj)
# s.get_web_content("https://zh.wikipedia.org/wiki/%E6%AD%BC-16")