dongzhaorui 3 年 前
コミット
780c181360

+ 28 - 9
find_source/crawler/defaults.py

@@ -1,3 +1,4 @@
+# -*- coding: utf-8 -*-
 
 
 TAGS_CAN_BE_REMOVE_IF_EMPTY = ['section', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'span']
@@ -42,17 +43,35 @@ USELESS_ATTR = {
 }
 
 
-KEYWORDS = {
-    '招标', '流标', '评标', '询价', '中标候选人', '抽签', '谈判', '中选', '意见征询',
-    '更正公告', '废标', '补遗', '议价', '邀请', '资格预审', '竞标', '变更', '遴选',
-    '磋商', '项目', '评审', '询比', '开标', '澄清', '比选', '中止', '采购', '竟价',
-    '招投标', '拟建', '成交', '中标', '竞争性谈判', '工程', '验收公告', '更正',
-    '单一来源', '变更公告', '合同', '违规', '评判', '监理', '竞价', '答疑',
-    '终止', '系统'
+# 需要被过滤掉的词组
+VOID_WORDS = {
+    '供应商登录', '流程', '登录', '下载', '管理局', '管理人员', '网', '采购人',
+    '协会', '帮助', '公司', '分类', '采购目录', '网站', '采购商', '说明',
+    '代理机构', '服务平台', '考核', '操作', '规定', '采购指南', '专家'
 }
+# 需要保留的关键信息
+VALID_WORDS = {
+    '竞标', '拟建', '管输', '国土', '疫苗', '拦标', '矿权', '协议', '答疑', '进出口产品', '林权',
+    '项目', '排污权', '开标', '矿业', '违规', '资源', '中标候选人', '机电设备', '协议供货', '中止', '合同',
+    '中选', '碳排放权', '行政处罚', '省本级', '竞价', '处罚', '中标', '企业增资', '系统', '招租', '发包',
+    '比选', '市级', '决定', '新闻中心', '省级', '经营权', '乡镇', '自然资源', '土地使用权', '最高限价', '更正',
+    '异常', '投诉', '废标', '变更', '询比', '交通', '资格审查', '资格预审', '招标', '产权', '工程',
+    '监督检查', '租赁', '政府采购', '抽签', '控制价', '转让', '入围', '国有产权', '竞争性', '征求', '结果',
+    '需求', '遴选', '成交', '耗材', '使用权', '劳务', '交易', '候选人', '交易进程', '机械', '网上商城',
+    '验收', '评判', '服务', '定标结果', '出让', '债券', '履约', '澄清', '标前公告', '采购', '更正公告',
+    '评审', '分包', '土地', '药品', '流标', '招投标', '水利', '公告信息', '货物', '建设', '未入围',
+    '审批核准', '市本级', '预中标', '出让公告', '电子卖场', '意见征询', '网上竞价', '意见', '拟批准',
+    '监理', '终止', '磋商', '征集', '评标', '其他', '资格入围', '单一来源', '土矿权', '煤炭',
+    '医药器械', '房屋', '验收公告', '补遗', '议价', '变更公告', '终(中)止', '批量采购', '暂停', '复审', '资产',
+    '邀请', '通知公告', '备案', '询价', '谈判', '中小企业', '分散采购', '中(终)止', '购买', '竟价',
+    '竞争性谈判', '定点', '耕地', '拍卖公告', '物资', '省', '市', '县/区',
+}
+
 
 FOOTER_TEXTS = {}
 PAGE_TEXTS = {'尾页', '下页', '下一页'}
 LOGIN_TEXTS = {'忘记密码', '登录', '注册'}
-NAV_TEXTS = {'政策', '办事指南', '首页', '党', '操作手册', '关于我们', '地图',
-             '建议意见', '法律声明', '信箱', '网安备', }
+NAV_TEXTS = {
+    '政策', '办事指南', '首页', '党', '操作手册', '关于我们', '地图',
+    '建议意见', '法律声明', '信箱', '网安备', '意见反馈', '客户服务', 'VIP服务'
+}

+ 7 - 17
find_source/crawler/download.py

@@ -117,28 +117,18 @@ class Downloader:
 
 class RenderDownloader(Downloader):
 
-    # def get(self, url, **kw):
-    #     splash_url = 'http://8.131.72.226:8998/render.html'
-    #     args = {
-    #         'url': url,
-    #         'timeout': 60,
-    #         'wait': 0.5,
-    #     }
-    #     resp = requests.get(splash_url, params=args, headers=headers)
-    #     return resp
-
     def get(self, url, **kw):
         splash_url = 'http://8.131.72.226:8998/render.json'
         args = {
             'url': url,
             'html': 1,
             'iframes': 1,
+            'headers': headers,
+            'timeout': kw.pop('timeout', 2),
+            'wait': kw.pop('wait', 0.5),
+            'viewport': kw.pop('viewport', 'full'),
         }
-        # splash_url = 'http://8.131.72.226:8998/render.html'
-        # args = {
-        #     'url': url,
-        #     'timeout': 60,
-        #     'wait': 0.5,
-        # }
-        resp = requests.get(splash_url, params=args, headers=headers)
+        resp = requests.post(splash_url,
+                             json=args,
+                             headers={'content-type': 'application/json'})
         return resp

+ 8 - 4
find_source/crawler/services/channel.py

@@ -1,3 +1,4 @@
+import json
 import os
 import pathlib
 from urllib.parse import urljoin
@@ -16,7 +17,7 @@ from crawler.utils import (
     remove_node,
     pre_parse,
     is_empty_element,
-    is_title,
+    check_text_by_words,
 )
 
 _base_path = pathlib.Path(__file__).parent
@@ -168,7 +169,7 @@ def strip_node(element: HtmlElement):
             # 节点文本(剔除左右空白、换行、回车符号)
             text = "".join("".join(node.xpath('./text()')).strip())
             # 关键词文本
-            non_title = is_title(text) is False
+            non_title = check_text_by_words(text) is False
             # 后裔a节点数量
             sub_tag_gt_0 = len(list(node.iterdescendants('a'))) == 0
             # 时间文本
@@ -272,7 +273,7 @@ def extract_data(source, base_url):
         for node in child.iterdescendants('a'):
             title = extract_text(node)
             href = urljoin(base_url, node.attrib.get('href'))
-            if is_title(title) and len(title) <= 15:
+            if check_text_by_words(title) and len(title) <= 15:
                 item = (title, href)
                 data.append(item)
         key = "{}_{}".format(child.tag.lower(), index)
@@ -311,7 +312,10 @@ def process_page(source):
 
 
 def bfs(response, base_url):
-    source = response.text
+    try:
+        source = response.json().get('html', '')
+    except json.decoder.JSONDecodeError:
+        source = response.text
     # show_html(source, file='1原始页.html')
     if len(source) == 0:
         return {}

+ 9 - 4
find_source/crawler/utils.py

@@ -12,7 +12,8 @@ from crawler.defaults import (
     USELESS_TAG,
     USELESS_ATTR,
     TAGS_CAN_BE_REMOVE_IF_EMPTY,
-    KEYWORDS,
+    VALID_WORDS,
+    VOID_WORDS
 )
 
 
@@ -227,9 +228,13 @@ def pre_parse(element):
     return element
 
 
-def is_title(val: str):
-    """检查数字、字母、中文的个数"""
-    for keyword in KEYWORDS:
+def check_text_by_words(val: str):
+    for word in VOID_WORDS:
+        search = re.search(word, val)
+        if search is not None:
+            return False
+
+    for keyword in VALID_WORDS:
         search = re.search(keyword, val)
         if search is not None:
             return True