x技术
# -*- coding: utf-8 -*-
# @Time : 2023/07/21 0021 21:46
# @Author : 张鑫
# @File : xnews
# @Project : PyCharm 2023.1.1
import json
import random
import re
import time
from urllib.parse import quote
from selenium import webdriver
import pymysql
import requests
from lxml import etree
from selenium.webdriver.common.by import By
def strip_tags(string, allowed_tags=''):
if allowed_tags != '':
# Get a list of all allowed tag names.
allowed_tags = allowed_tags.split(',')
allowed_tags_pattern = ['</?' + allowed_tag + '[^>]*>' for allowed_tag in allowed_tags]
all_tags = re.findall(r'<[^>]+>', string, re.I)
not_allowed_tags = []
tmp = 0
for tag in all_tags:
for pattern in allowed_tags_pattern:
rs = re.match(pattern, tag)
if rs:
tmp += 1
else:
tmp += 0
if not tmp:
not_allowed_tags.append(tag)
tmp = 0
for not_allowed_tag in not_allowed_tags:
string = re.sub(re.escape(not_allowed_tag), '', string)
else:
# If no allowed tags, remove all.
string = re.sub(r'<[^>]*?>', '', string)
return string
# 上传图片到服务器
def get_our_pic(content_url):
upload_picurl = 'https://www.china-mcc.com/index/grabfile/index.html'
data = {
'path': content_url
}
html = requests.post(url=upload_picurl, data=data).json()
our_pic_url = html['file_url']
return our_pic_url
# 上传PDF到服务器
def get_our_pdf(content_url):
upload_picurl = 'https://www.china-mcc.com/index/grabfile/pdf.html'
data = {
'path': content_url
}
html = requests.post(url=upload_picurl, data=data).json()
our_pic_url = html['file_url']
return our_pic_url
dict_category = {'企业分类': '1', '产品分类': '2', '技术分类': '3', '需求分类': '4', '会议分类': '5', '活动分类': '6',
'资讯分类': '7', '图库分类': '8', '视频分类': '9', '企业性质': '10', '成熟度': '11', '应用情况': '12',
'成果类型': '13', '转换方式': '14', '矿山': '15', '冶金': '16', '材料': '199', '环保': '18',
'检测': '19', '其他': '105', '矿山设备': '21', '冶金设备': '22', '材料制备及加工设备': '23',
'环境保护设备': '24', '分析检测设备': '25', '矿山技术': '26', '冶金技术': '27',
'材料制备及加工技术': '28', '环境保护技术': '29', '分析检测技术': '30', '矿山需求': '31',
'冶金需求': '32', '材料制备及加工需求': '33', '环境保护需求': '34', '分析检测需求': '35',
'矿山行业': '36', '冶金行业': '37', '材料行业': '38', '环保行业': '39', '检测行业': '40',
'其他行业': '41', '线上活动': '42', '线下活动': '43', '技术资讯': '44', '产品资讯': '45',
'新闻资讯': '46', '企业宣传': '50', '图说产品': '48', '图说技术': '49', '会议视频': '51',
'产品视频': '52', '技术讲解': '53', '专题采访': '54', '应用案例': '55', '生产型': '56', '技术型': '57',
'服务型': '58', '实验室': '59', '小试': '60', '中试': '61', '形成产品': '62', '实际应用': '64',
'技术转让': '76', '规模化生产': '66', '未转让或应用': '67', '发明专利': '69', '新产品': '70',
'新装置': '71', '新材料': '72', '新工艺': '73', '其它': '74', '合作研发': '75', '技术许可': '77',
'技术入股': '78', '创业融资': '79', '股权融资': '80', '探矿': '175', '采矿': '176', '选矿': '177',
'通用': '178', '火法冶金': '179', '湿法冶金': '180', '电冶金': '181', '真空冶金': '182',
'功能材料': '183', '复合材料': '184', '新能源材料': '185', '合金材料': '204', '材料加工': '187',
'废水处理': '188', '大气治理': '189', '固/危废处置': '190', '土壤修复': '191', '物理检测': '192',
'化学分析': '193', '力学检测': '194', '无损检测': '195', '失效分析': '196', '环境检测': '197',
'探矿设备': '106', '采矿设备': '107', '选矿设备': '108', '通用设备': '109', '火法冶金设备': '110',
'湿法冶金设备': '111', '电冶金设备': '112', '真空冶金设备': '113', '功能材料设备': '114',
'复合材料设备': '115', '新能源材料设备': '116', '合金材料设备': '117', '加工设备': '118',
'废水处理设备': '119', '大气治理设备': '120', '固/危废处置设备': '121', '土壤修复设备': '122',
'物理检测设备': '123', '化学分析设备': '124', '力学检测设备': '125', '无损检测设备': '126',
'失效分析设备': '127', '环境检测设备': '128', '探矿技术': '129', '采矿技术': '130', '选矿技术': '131',
'通用技术': '132', '火法冶金技术': '133', '湿法冶金技术': '134', '电冶金技术': '135',
'真空冶金技术': '136', '功能材料技术': '137', '复合材料技术': '138', '新能源材料技术': '139',
'合金材料技术': '140', '加工技术': '141', '废水处理技术': '142', '大气治理技术': '143',
'固/危废处置技术': '144', '土壤修复技术': '145', '物理检测技术': '146', '化学分析技术': '147',
'力学检测技术': '148', '无损检测技术': '149', '失效分析技术': '150', '环境检测技术': '151',
'探矿需求': '152', '采矿需求': '153', '选矿需求': '154', '通用需求': '155', '火法冶金需求': '156',
'湿法冶金需求': '157', '电冶金需求': '158', '真空冶金需求': '159', '功能材料需求': '160',
'复合材料需求': '161', '新能源材料需求': '162', '合金材料需求': '163', '加工需求': '164',
'废水处理需求': '165', '大气治理需求': '166', '固/危废处置需求': '167', '土壤修复需求': '168',
'物理检测需求': '169', '化学分析需求': '170', '力学检测需求': '171', '无损检测需求': '172',
'失效分析需求': '173', '环境检测需求': '174', '综合': '198', '矿山材料': '200', '冶金材料': '201',
'环保材料': '202', '锂电设备': '203', '其它材料': '205'}
dict_area = {'北京': '32', '天津': '33', '上海': '34', '重庆': '35', '河北': '36', '山西': '47',
'辽宁': '58',
'吉林': '72', '黑龙江': '81', '江苏': '94', '浙江': '107', '安徽': '118', '福建': '134',
'江西': '143',
'山东': '154', '河南': '170', '湖北': '188', '湖南': '204', '广东': '218', '海南': '239',
'四川': '242',
'贵州': '263', '云南': '272', '陕西': '288', '甘肃': '298', '青海': '312', '内蒙': '320',
'广西': '332',
'西藏': '346', '宁夏': '353', '新疆': '358', '石家庄': '36', '唐山': '37', '秦皇岛': '38',
'邯郸': '39',
'邢台': '40', '保定': '41', '张家口': '42', '承德': '43', '沧州': '44', '廊坊': '45',
'衡水': '46',
'太原': '47', '大同': '48', '朔州': '49', '忻州': '50', '阳泉': '51', '吕梁': '52',
'晋中': '53',
'长治': '54', '晋城': '55', '临汾': '56', '运城': '57', '沈阳': '58', '大连': '59',
'鞍山': '60',
'抚顺': '61', '本溪': '62', '丹东': '63', '锦州': '64', '营口': '65', '阜新': '66',
'辽阳': '67',
'盘锦': '68', '铁岭': '69', '朝阳': '70', '葫芦岛': '71', '长春': '72', '四平': '74',
'辽源': '75',
'通化': '76', '白山': '77', '松原': '78', '白城': '79', '延边朝鲜族自治州': '80',
'哈尔滨': '81',
'齐齐哈尔': '82', '鸡西': '83', '鹤岗': '84', '双鸭山': '85', '大庆': '86',
'伊春': '87', '佳木斯': '88',
'七台河': '89', '牡丹江': '90', '黑河': '91', '绥化': '92', '大兴安岭地区': '93',
'南京': '94',
'无锡': '95', '徐州': '96', '常州': '97', '苏州': '98', '南通': '99', '连云港': '100',
'淮安': '101',
'盐城': '102', '扬州': '103', '镇江': '104', '泰州': '105', '宿迁': '106',
'杭州': '107', '宁波': '108',
'温州': '109', '绍兴': '110', '湖州': '111', '嘉兴': '112', '金华': '113',
'衢州': '114', '台州': '115',
'丽水': '116', '舟山': '117', '合肥': '118', '芜湖': '119', '蚌埠': '120',
'淮南': '121', '马鞍山': '122',
'淮北': '123', '铜陵': '124', '安庆': '125', '黄山': '126', '阜阳': '127',
'宿州': '128', '滁州': '129',
'六安': '130', '宣城': '131', '池州': '132', '亳州': '133', '福州': '134',
'厦门': '135', '漳州': '136',
'泉州': '137', '三明': '138', '莆田': '139', '南平': '140', '龙岩': '141',
'宁德': '142', '南昌': '143',
'九江': '144', '上饶': '145', '抚州': '146', '宜春': '147', '吉安': '148',
'赣州': '149', '景德镇': '150',
'萍乡': '151', '新余': '152', '鹰潭': '153', '济南': '154', '青岛': '155',
'淄博': '156', '枣庄': '157',
'东营': '158', '烟台': '159', '潍坊': '160', '济宁': '161', '泰安': '162',
'威海': '163', '日照': '164',
'滨州': '165', '德州': '166', '聊城': '167', '临沂': '168', '菏泽': '169',
'郑州': '170', '开封': '171',
'洛阳': '172', '平顶山': '173', '安阳': '174', '鹤壁': '175', '新乡': '176',
'焦作': '177', '濮阳': '178',
'许昌': '179', '漯河': '180', '三门峡': '181', '商丘': '182', '周口': '183',
'驻马店': '184',
'南阳': '185', '信阳': '186', '济源': '187', '武汉': '188', '黄石': '189',
'十堰': '190', '宜昌': '191',
'襄阳': '192', '鄂州': '193', '荆门': '194', '孝感': '195', '荆州': '196',
'黄冈': '197', '咸宁': '198',
'随州': '199', '恩施土家族苗族自治州': '200', '仙桃': '201', '潜江': '202',
'天门': '203', '长沙': '204',
'株洲': '205', '湘潭': '206', '衡阳': '207', '邵阳': '208', '岳阳': '209',
'常德': '210', '张家界': '211',
'益阳': '212', '娄底': '213', '郴州': '214', '永州': '215', '怀化': '216',
'湘西土家族苗族自治州': '217',
'广州': '218', '韶关': '219', '深圳': '220', '珠海': '221', '汕头': '222',
'佛山': '223', '江门': '224',
'湛江': '225', '茂名': '226', '肇庆': '227', '惠州': '228', '梅州': '229',
'汕尾': '230', '河源': '231',
'阳江': '232', '清远': '233', '东莞': '234', '中山': '235', '潮州': '236',
'揭阳': '237', '云浮': '238',
'海口': '239', '三亚': '240', '三沙': '241', '成都': '242', '自贡': '243',
'攀枝花': '244', '泸州': '245',
'德阳': '246', '绵阳': '247', '广元': '248', '遂宁': '249', '内江': '250',
'乐山': '251', '南充': '252',
'眉山': '253', '宜宾': '254', '广安': '255', '达州': '256', '雅安': '257',
'巴中': '258', '资阳': '259',
'阿坝藏族羌族自治州': '260', '甘孜藏族自治州': '261', '凉山彝族自治州': '262',
'贵阳': '263',
'遵义': '264', '六盘水': '265', '安顺': '266', '毕节': '267', '铜仁': '268',
'黔东南苗族侗族自治州': '269',
'黔南布依族苗族自治州': '270', '黔西南布依族苗族自治州': '271', '昆明': '272',
'曲靖': '273',
'玉溪': '274', '昭通': '275', '保山': '276', '丽江': '277', '普洱': '278',
'临沧': '279',
'德宏傣族景颇族自治州': '280', '怒江傈僳族自治州': '281', '迪庆藏族自治州': '282',
'大理白族自治州': '283',
'楚雄彝族自治州': '284', '红河哈尼族彝族自治州': '285', '文山壮族苗族自治州': '286',
'西双版纳傣族自治州': '287', '西安': '288', '宝鸡': '289', '咸阳': '290',
'铜川': '291', '渭南': '292',
'延安': '293', '榆林': '294', '汉中': '295', '安康': '296', '商洛': '297',
'兰州': '298', '嘉峪关': '299',
'金昌': '300', '白银': '301', '天水': '302', '武威': '303', '张掖': '304',
'平凉': '305', '酒泉': '306',
'庆阳': '307', '定西': '308', '陇南': '309', '临夏回族自治州': '310',
'甘南藏族自治州': '311',
'西宁': '312', '海东': '313', '海北藏族自治州': '314', '黄南藏族自治州': '315',
'海南藏族自治州': '316',
'果洛藏族自治州': '317', '玉树藏族自治州': '318', '海西蒙古族藏族自治州': '319',
'呼和浩特': '320',
'包头': '321', '乌海': '322', '赤峰': '323', '通辽': '324', '鄂尔多斯': '325',
'呼伦贝尔': '326',
'巴彦淖尔': '327', '乌兰察布': '328', '兴安盟': '329', '锡林郭勒盟': '330',
'阿拉善盟': '331',
'南宁': '332', '柳州': '333', '桂林': '334', '梧州': '335', '北海': '336',
'崇左': '337', '来宾': '338',
'贺州': '339', '玉林': '340', '百色': '341', '河池': '342', '钦州': '343',
'防城港': '344', '贵港': '345',
'拉萨市': '346', '日喀则市': '347', '昌都市': '348', '林芝市': '349', '山南市': '350',
'那曲市': '351',
'阿里地区': '352', '银川': '353', '石嘴山': '354', '吴忠': '355', '固原': '356',
'中卫': '357',
'乌鲁木齐': '358', '克拉玛依': '359', '吐鲁番': '360', '哈密': '361',
'阿克苏地区': '362',
'喀什地区': '363', '和田地区': '364', '昌吉回族自治州': '365',
'博尔塔拉蒙古自治州': '366',
'巴音郭楞蒙古自治州': '367', '克孜勒苏柯尔克孜自治州': '368',
'伊犁哈萨克自治州': '369', '塔城地区': '370',
'阿勒泰地区': '371', '自治区直辖县级行政单位': '372', '东城区': '2153',
'西城区': '374', '朝阳区': '845',
'丰台区': '376', '石景山区': '377', '海淀区': '378', '顺义区': '379', '通州区': '1072',
'大兴区': '381',
'房山区': '382', '门头沟区': '383', '昌平区': '384', '平谷区': '385', '密云区': '386',
'怀柔区': '387',
'延庆区': '388', '和平区': '743', '河东区': '1616', '河西区': '391', '南开区': '392',
'河北区': '393',
'红桥区': '394', '滨海新区': '395', '东丽区': '396', '西青区': '397', '津南区': '398',
'北辰区': '399',
'武清区': '400', '宝坻区': '401', '宁河区': '402', '静海区': '403', '蓟州区': '404',
'黄浦区': '405',
'徐汇区': '406', '长宁区': '407', '静安区': '408', '普陀区': '1210', '虹口区': '410',
'杨浦区': '411',
'闵行区': '412', '宝山区': '957', '嘉定区': '414', '浦东新区': '415', '金山区': '416',
'松江区': '417',
'青浦区': '418', '奉贤区': '419', '崇明区': '420', '渝中区': '421', '万州区': '422',
'涪陵区': '423',
'大渡口区': '424', '江北区': '1137', '沙坪坝区': '426', '九龙坡区': '427',
'南岸区': '428',
'北碚区': '429', '綦江区': '430', '大足区': '431', '渝北区': '432', '巴南区': '433',
'黔江区': '434',
'长寿区': '435', '江津区': '436', '合川区': '437', '永川区': '438', '南川区': '439',
'璧山区': '440',
'铜梁区': '441', '潼南区': '442', '荣昌区': '443', '开州区': '444', '梁平区': '445',
'武隆区': '446',
}
# 链接mysql数据库
connect = pymysql.Connect(
host='127.0.0.1',
port=3306,
user='root',
passwd='123456',
db='xnews',
charset='utf8mb4'
)
def get_msg(keywords, category_id, page_header, page_num):
driver = webdriver.Chrome()
# pn=10*(page-1)
for pages in range(page_header, page_num):
time.sleep(random.randint(15, 18))
url = f'https://www.baidu.com/s?wd=site:www.xjishu.com%20{keywords}&pn={pages * 10}'
print(f'第{pages + 1}页:{url}*****************')
driver.get(url)
driver.maximize_window()
driver.execute_script("var q=document.documentElement.scrollTop=10000")
time.sleep(random.randint(5, 8))
html = driver.page_source
tree = etree.HTML(html)
second_url_list = tree.xpath('//div[@id="content_left"]//h3//a//@href')
for second_url in second_url_list:
time.sleep(random.randint(3, 5))
print(f'详情页链接:{second_url}')
driver.get(second_url)
html_second = driver.page_source
tree_second = etree.HTML(html_second)
# 标题
title = ''.join(tree_second.xpath('//h1[@class="title"]//text()')).replace(' ', '').replace('\r',
'').strip()
# 文本内容
content = tree_second.xpath('//div[@class="art-body"]//text()')
if content != []:
# 内容
neirong = tree_second.xpath('//div[@class="art-body"]')[0]
content = ''.join(etree.tostring(neirong, encoding='utf-8').decode()).split(
'</tbody>')[0]
content = strip_tags(content, allowed_tags='br,img,hr,a,table,tr,th,td,tbody').replace('original',
'src').replace(
'\u200b', '').strip()
content = re.sub(r'\xa0', "", content)
content = re.sub(r' ', "", content)
content = re.sub(r'style="border:0px;"', "", content)
content = re.sub('\s', ' ', content)
content = re.sub('\ue681', ' ', content)
content = re.sub('<a(.*?)>', '', content)
content = re.sub('<a>', '', content)
content = re.sub('</a>', '', content)
content = re.sub('<br(.*?)>', '', content)
content = re.sub('<br>', '<br><br>', content)
content = re.sub('</p>', '<br><br>', content)
content_sub = re.findall('style="(.*?)"', content)
if content_sub != []:
content_sub = content_sub[0]
content = re.sub('"' + content_sub + '"', '', content)
content = re.sub('style=', '', content)
content = re.sub(r'\xa0', "", content)
content = re.sub(r' ', "", content)
content = re.sub(r'猜你喜欢', "", content)
content = re.sub('\s', ' ', content)
# intro = tree_second.xpath('//div[@class="art-body"]//text()')[0:10]
# intro = "".join(intro).strip()
# print(f'intro:{len(intro)}')
# 技术所有人
msg_list = tree_second.xpath('//ul//li//span//text()')
company = ''
for msg in msg_list:
if '技术所有人:' in msg:
company = ''.join(msg).replace('技术所有人:', '')
# owner:归属
if '大学' or '公司' or '所' in company:
owner = '公司'
else:
owner = '个人'
tag = ''.join(tree_second.xpath('//div[@class="art-meta"][2]//span//a[3]//@title')[-2:])
# 左上方展示图片
pic_left_new = tree_second.xpath('//div[@class="art-body"]//img//@src')
if len(pic_left_new) == 0:
pic = ''
else:
print(f'左上角原链接:{(pic_left_new[0])}')
pic = pic_left_new[0].replace('\\', "/")
pic = get_our_pic(pic)
print(f'左上角转换后链接:{pic}')
for pic_left in pic_left_new:
print(f'原图片:{pic_left}')
our_pic = get_our_pic(pic_left)
print(f'转换后的图片:{our_pic}')
content = content.replace(pic_left, our_pic)
# 访问量
hit = random.randint(100, 1000)
cursor = connect.cursor()
sql1 = 'select title from tb_tech'
connect.ping(reconnect=True)
cursor.execute(sql1)
ir_md5_dec = cursor.fetchall()
# 把需要查询的数据转变为元组
md5 = tuple([title], )
if md5 in ir_md5_dec:
pass
print('数据已存在')
else:
print(f'标题:{title}')
print(f'归属:{owner}')
print(f'申请专利人:{company}')
print(f'图片:{pic}')
# print(f'简介:{intro}')
print(f'内容:{content}')
print(f'访问量:{hit}')
print(f'标签:{title}')
print(f'应用领域ID:{category_id}')
print('\n')
data_list = {
'title': title,
'owner': owner,
'company': company,
'pic': pic,
'tag': tag,
# 'intro': intro,
'content': content,
'hit': hit,
'category_id': category_id,
}
sql = f"""insert into tb_tech{str(tuple(data_list.keys())).replace("'", "")} values {str(tuple(data_list.values()))};"""
cursor.execute(sql)
connect.ping(reconnect=True)
# 提交数据库
connect.commit()
ir_idd = int(connect.insert_id())
print('数据库自增id', ir_idd, '数据')
print("tb_tech表数据存储成功!", )
print('提交成功')
driver.get(url)
time.sleep(random.randint(10, 15))
if pages == 0:
driver.find_element(by=By.XPATH, value='//a[@class="n"]').click()
else:
driver.find_element(by=By.XPATH, value='//a[@class="n"][2]').click()
url = driver.current_url
time.sleep(random.randint(5, 8))
driver.close()
driver.quit()
connect.close()
if __name__ == '__main__':
keywords = quote('合金材料')
get_msg(keywords, 204, 0, 4)
'''
https://www.baidu.com/s?wd=site%3Awww.xjishu.com%20%E6%9C%89%E8%89%B2%E9%87%91%E5%B1%9E&pn=10&oq=site%3Awww.xjishu.com%20%E6%9C%89%E8%89%B2%E9%87%91%E5%B1%9E&ct=2097152&ie=utf-8&si=www.xjishu.com&rsv_pq=df50febb00072e5a&rsv_t=19f033Bc5Resw86HaMvTMqNx%2BYZiKQxOstCgWIZSg5GMukie286b2SuppMg&gpc=stf%3D1656308599%2C1687844599%7Cstftype%3D1&tfflag=1&rsv_jmp=slow
https://www.baidu.com/s?wd=site%3Awww.xjishu.com%20%E6%9C%89%E8%89%B2%E9%87%91%E5%B1%9E&pn=20&oq=site%3Awww.xjishu.com%20%E6%9C%89%E8%89%B2%E9%87%91%E5%B1%9E&ct=2097152&ie=utf-8&si=www.xjishu.com&rsv_pq=b642285700004eab&rsv_t=845eqGsSuNd8MBQwq%2F8ZN%2BaqkuyrQ01i2Jcd3E%2Btu50GbAr8jpENuWJofwk&gpc=stf%3D1656308599%2C1687844599%7Cstftype%3D1&tfflag=1&rsv_jmp=slow
'''