完整代码链接:https://github.com/JohnWSY/crawlproject-gjypjd
从svn download需求文档,明确分工为国家药监局网站全网内容爬取,根据文档与需求进行对接
分三级目录
一级目录:共有六大类,40余种小类 正则匹配,进入超链接
二级目录:实现翻页,确定穷尽页的停止机制
详情页 根据需求,所需爬取的内容都在最后的详情页
由以上过程中,发现由二级目录到详情页、以及二级目录的翻页url并不改变,说明网站是ajax请求,即异步javascipt和HTML或XML
所以不能从网页匹配http抓取链接。
只得采取笨方法,通过观察一级目录的网页HTML寻找url的规律,进行拼接。在进入网页的调试页面时,又出现了问题。
进入网页调试界面后,source显示pause in debugger无法继续点击操作,html卡在标签下,content为乱码
通过点击调试台右上角deactivate breakpoints跳过断点,,然后就可以想点哪里点哪里
观察一级目录下的各个分类的content
对比点进目录链接后的headers-request url可以发现有一定的相似度,所以试着采用拼接url的方法进行对服务器的访问,可以得到以下页面
虽然渲染效果不如原网页,而且点击没有继续链接,但是可以通过正则匹配此页的html字段继续进行下一级的url拼接
但还是由于网页的ajax请求,翻页不跳转,所以需要另寻找方法进行翻页遍历,我们开始观察每一页的headers头部信息
我发现头部信息中的form data中的curstart参数就是所在页对应的页码,于是我心生一计,将form data中的所有参数还原为js格式(即点击view source)可以得到一串字符,拼接到下图发现的请求url前面相同的部分也许可以调出页面,实现for循环遍历二级目录页,并最终实现
for i in range(1,457):
url='http://app1.sfda.gov.cn/datasearchcnda/face3/search.jsp?tableId=121&State=1&bcId=152894035121716369704750131820&State=1&curstart='+str(i)+'&State=1&tableName=TABLE121&State=1&viewtitleName=COLUMN1615&State=1&viewsubTitleName=COLUMN1618,COLUMN1616&State=1&tableView=%25E5%2585%25A8%25E5%259B%25BD%25E8%258D%25AF%25E5%2593%2581%25E6%258A%25BD%25E6%25A3%2580&State=1&cid=0&State=1&ytableId=0&State=1&searchType=search&State=1'
self.crawl(url,cookies=d,callback=self.index_page)
至此,我们回想一级目录进入二级目录的url拼接方式,发现无法继续执行二级目录的翻页,因为二级目录翻页所需的某些参数信息是特定的(eg:tableId),参照需求所需要的详情页信息,决定为一级目录下的40余类分别建立代码文件,也便于后期的数据清洗。
二级目录可通过循环遍历翻页,采用相同的思想,尝试从二级目录的html文件查找最终详情页的访问方式。发现依然可以采用url拼接的方法,遍历访问二级目录页的每条详情页,并保存其text文件。至此,爬取思路完全确定,开始实现代码。
因为项目统一管理的要求,采用pyspider框架开展爬虫项目,个人感觉pyspider框架的调试功能以及时间参数的设置非常实用
尤其在学习使用的过程中,尝试爬取豆瓣电影top250尝试总结出电影打分人数与电影评分之间的关系。虽然最后可视化的结果显示没有明显的关系
但是在过程中使用了框架内置的css选择器功能,通过web键直接调取页面至框架内,通过css选择器直接插入代码匹配的html标签,非常好用,省去打开浏览器调用调控台的操作。
代码完成后的结果却出现了问题,输出框中的content乱码,查看网页源代码发现网页为gbk2312编码,尝试解码
ASCII 加入GB2312 Unicode 存储传输 UTF-8
'(str) '.encode()用括号内的格式编码 ’ '.decode() 用括号内的编码解码位str
结果却还是不变,这时猛然想起网页的断点问题,不是手动解决这么简单的。查询原因,有一个人提到也许与伪装浏览器的头部缺少cookie参数有关
我在全局声明头部中加入了cookies参数,就可以得到结果,但是之后发现再次为领导演示结果时却为空
debug代码发现,从二级目录并未匹配出相应的详情页url字段,当从新更换一个cookie参数,代码又可以跑通了,所以怀疑是cookie的时效问题
class Handler(BaseHandler):
crawl_config = {'headers':{
'User-Agent':'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.169 Safari/537.36'
}
}
@every(minutes=24 * 60)
def on_start(self):
cookies='JSESSIONID=549B26AF6C4ACAE47F799A3D578B4754.7; FSSBBIl1UgzbN7N82S=xyyKdvxgtlj.G7MvXIyuzgZdAK6TxH_R0wXmYbDoiPab8d4.YHE2_Y5W2A_FpyG4; security_session_verify=3e6bcb698895fc61dce2d3ff3b39501a; FSSBBIl1UgzbN7N82T=2LwZLdYmXTxN7NnD5LAGgMXDFSJO5E2myM0jyg.HLlD28hwoV9X_6K5pCCLmzHJEo784W4KBSvC8pT_KcCoxg9gv3MwjVXW0PyUoKozu7uiCw.918QEumKcV6t_iz4yCSQ6PLUj0aM.oQTSFzWjKCBPieTII_5H7.mrqWVT5MLc1qZFKQJxjPhnHDT3HSDRO5xyAoU3Niaks5zjps9F97foHd0IDrwlB2mDrstJJWbD28jSANzZbY72KEBBY_81eu517P6RA.SgCqP7H_58b4OScuaYwDCZaVAqjrzKbZ17DEPA'
s1=cookies.replace(';',"','")
s2=s1.replace('=',"':'")
s3="{'"+s2+"'}"
s4=s3.replace(' ','')
d=eval(s4)
for i in range(1,457):
url='http://app1.sfda.gov.cn/datasearchcnda/face3/search.jsp?tableId=121&State=1&bcId=152894035121716369704750131820&State=1&curstart='+str(i)+'&State=1&tableName=TABLE121&State=1&viewtitleName=COLUMN1615&State=1&viewsubTitleName=COLUMN1618,COLUMN1616&State=1&tableView=%25E5%2585%25A8%25E5%259B%25BD%25E8%258D%25AF%25E5%2593%2581%25E6%258A%25BD%25E6%25A3%2580&State=1&cid=0&State=1&ytableId=0&State=1&searchType=search&State=1'
self.crawl(url,cookies=d,callback=self.index_page)
@config(age=10 * 24 * 60 * 60)
def index_page(self, response):
for each in response.doc('a[href^="javascript:commitForECMA(callbackC,"]').items():
url='http://app1.sfda.gov.cn/datasearchcnda/face3/'+each.attr.href.split("'")[1]
self.crawl(url,cookies=response.cookies,callback=self.detail_page)
def detail_page(self,response):
return{
'url':response.url,
'content':response.text
}
这组搭档简直强大,一手page_source让你无欲无求
首先要pip install selenium 然后再根据电脑使用的浏览器下载对应版本的webdriver,然后就是showtime
pyspider框架在这个项目弃用了,但是我们确定的爬取思路还是正确的,延续使用原有的爬取思路
import re
from selenium import webdriver
from gjypjd.utils import exetcute_sql,if_headless
import pymysql
def main():
option=None
#配置文件中开启是否无头,生产阶段关闭
if if_headless():
option = webdriver.ChromeOptions()
option.add_argument(argument='headless')
for i in range(1, 470): # 遍历469个一级目录网页
browser = webdriver.Chrome(chrome_options=option)
url_1 = 'http://app1.sfda.gov.cn/datasearchcnda/face3/search.jsp?tableId=32&State=1&bcId=152904813882776432084296368957&State=1&curstart='+str(i)+'&State=1&tableName=TABLE32&State=1&viewtitleName=COLUMN302&State=1&viewsubTitleName=COLUMN303,COLUMN299&State=1&tableView=%25E5%259B%25BD%25E4%25BA%25A7%25E8%258D%25AF%25E5%2593%2581%25E5%2595%2586%25E5%2593%2581%25E5%2590%258D&State=1&cid=0&State=1&ytableId=0&State=1&searchType=search&State=1'
browser.get(url_1)
s = browser.page_source.replace('amp;', '')
m = re.findall(r'content.jsp\?tableId=32&tableName=TABLE32&tableView=国产药品商品名&Id=\d+', s, re.M)
browser.close()
for j in range(len(m)):
url_2 = 'http://app1.sfda.gov.cn/datasearchcnda/face3/' + m[j]
browser = webdriver.Chrome(chrome_options=option)
browser.get(url_2)
sql = "insert into t_gcypspm(c_bh, dt_insertTime, c_url, b_content) VALUES (REPLACE(UUID(),\"-\",\"\"), sysdate(), %s,%s)"
exetcute_sql(sql, [url_2,browser.page_source])
# pickle.loads(s) 可用该方法将乱码汉字转换
browser.close()
if __name__ == '__main__':
main()
import configparser
import pymysql
import logging
def logger():
logging.basicConfig(format='%(asctime)s - %(pathname)s[line:%(lineno)d] - %(levelname)s: %(message)s',
level=logging.INFO)
logger = logging.getLogger('gjypjd')
return logger
def if_headless():
cf = configparser.ConfigParser()
cf.read('./conf/common.ini')
headless = cf.get('webdriver', 'headless')
if headless.lower() == 'true':
return True
return False
def get_db_conf():
"""
获取数据库配置信息
:return:
"""
cf = configparser.ConfigParser()
cf.read('./conf/common.ini')
# print(cf.options("db"))
db_ip = cf.get('db', 'db_ip')
db_port = cf.getint('db', 'db_port')
db_user = cf.get('db', 'db_user')
db_password = cf.get('db', 'db_password')
db_name = cf.get('db', 'db_name')
db_encoding = cf.get('db', 'db_encoding')
return [db_ip, db_port, db_user, db_password, db_name, db_encoding]
def get_connection():
conf = get_db_conf()
return pymysql.connect(host=conf[0], port=conf[1], user=conf[2], password=conf[3], database=conf[4],
charset=conf[5])
def exetcute_sql(sql, params):
"""
执行带有参数的sql
:param sql:
:param params:
:return:
"""
conn = get_connection()
try:
with conn.cursor() as cursor:
cursor.execute(sql, params)
logger().info('success execute {}'.format(params[0]))
conn.commit()
except:
logger().error('error execute {}'.format(params[0]))
conn.rollback()
finally:
conn.close()
def select_sql_first(sql, params=None):
"""
执行带有参数的sql,获取第一条数据
:param sql:
:param params:
:return:
"""
conn = get_connection()
try:
with conn.cursor() as cursor:
if params:
cursor.execute(sql, params)
else:
cursor.execute(sql)
data = cursor.fetchone()
return data
except:
logger().error('error execute {}'.format(sql))
return None
finally:
conn.close()
def if_exists(url, tableName):
"""
检查URL是否存在 如果存在就不进行爬取
:param url:
:return:
"""
sql = 'select count(*) from {} where c_url = \'{}\''.format(tableName, url)
result = select_sql_first(sql)
if result[0] == 1:
return True
return False
/*
Navicat Premium Data Transfer
Source Server : 172.18.15.130_3306
Source Server Type : MySQL
Source Server Version : 50726
Source Host : 172.18.15.130:3306
Source Schema : webdriverdb
Target Server Type : MySQL
Target Server Version : 50726
File Encoding : 65001
Date: 19/06/2019 14:57:40
*/
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;
-- ----------------------------
-- Table structure for t_jkypspm
-- ----------------------------
DROP TABLE IF EXISTS `t_jkypspm`;
CREATE TABLE `t_jkypspm` (
`c_bh` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '编号',
`dt_insertTime` datetime(0) DEFAULT NULL COMMENT '插入时间',
`c_url` varchar(300) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '数据url',
`b_content` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci COMMENT '内容',
`c_json` varchar(3000) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '数据对应的json',
PRIMARY KEY (`c_bh`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '进口药品商品名' ROW_FORMAT = Dynamic;
SET FOREIGN_KEY_CHECKS = 1;
但是在数据库的结果中,contetnt汉字部分乱码,因为blob格式为二进制,所以使用pickle模块dumps()函数对其进行序列化,并在数据清洗中使用loads()方法反序列化可得到汉字,但是有些麻烦,跟负责人沟通后,改用text格式存储page_source乱码问题不再出现,并且决定在代码中加入json解析直接得到需求对应的字段,省去后期的数据清洗
\# 化妆品行政许可检验机构
import pickle
import re
from selenium import webdriver
from gjypjd.utils import exetcute_sql,if_headless,if_exists
import json
def main():
option=None
#配置文件中开启是否无头,生产阶段关闭
if if_headless():
option = webdriver.ChromeOptions()
option.add_argument(argument='headless')
for i in range(1, 4): # 遍历3个一级目录网页
browser = webdriver.Chrome(chrome_options=option)
url_1 = 'http://app1.sfda.gov.cn/datasearchcnda/face3/search.jsp?tableId=108&State=1&bcId=152904558282171636476541922479&State=1&curstart='+str(i)+'&State=1&tableName=TABLE108&State=1&viewtitleName=COLUMN1416&State=1&viewsubTitleName=COLUMN1421&State=1&tableView=%25E5%258C%2596%25E5%25A6%2586%25E5%2593%2581%25E8%25A1%258C%25E6%2594%25BF%25E8%25AE%25B8%25E5%258F%25AF%25E6%25A3%2580%25E9%25AA%258C%25E6%259C%25BA%25E6%259E%2584&State=1&cid=0&State=1&ytableId=0&State=1&searchType=search&State=1'
browser.get(url_1)
s = browser.page_source.replace('amp;', '')
m = re.findall(r'content.jsp\?tableId=108&tableName=TABLE108&tableView=化妆品行政许可检验机构&Id=\d+', s, re.M)
browser.close()
for j in range(len(m)):
url_2 = 'http://app1.sfda.gov.cn/datasearchcnda/face3/' + m[j]
if if_exists(url_2, 't_hzpxzxkjyjg'):
continue
browser = webdriver.Chrome(chrome_options=option)
browser.get(url_2)
sql = "insert into t_hzpxzxkjyjg(c_bh, dt_insertTime, c_url, b_content, c_json) VALUES (REPLACE(UUID(),\"-\",\"\"), sysdate(), %s,%s,%s)"
exetcute_sql(sql, [url_2, browser.page_source, parse2json(browser.page_source)])
# pickle.loads(s) 可用该方法将乱码汉字转换
browser.close()
def parse2json(html):
"""
检验机构名称jyjgmc
联系地址lxdz
联系人lxr
联系电话lxdh
传真cz
机构类别jglb
检验项目jyxm
:return:json
"""
# 初始化,避免取不到的情况下为空值
result_json = dict()
# 批准文号
reg_dict = dict()
reg_dict['jyjgmc'] = r"检验机构名称\s*(.*)"
reg_dict['lxdz'] = r"联系地址\s*(.*)"
reg_dict['lxr'] = r"联系人\s*(.*)"
reg_dict['lxdh'] = r"联系电话\s*(.*)"
reg_dict['cz'] = r"传真\s*(.*)"
reg_dict['jglb'] = r"机构类别\s*(.*)"
reg_dict['jyxm'] = r"检验项目\s*(.*)"
for i, v in reg_dict.items():
reg_search = re.search(v, html)
if reg_search is not None:
result_json[i] = reg_search.group(1)
else:
result_json[i] = ''
return json.dumps(result_json, ensure_ascii=False)
if __name__ == '__main__':
main()
至此,轰轰烈烈的项目就基本结束了,剩下的只是重复性的调试一级目录内的40余种小类,查看数据库中的结果是否正确
项目并没有结束,在吹响胜利号角的时候,发现了新的问题,那就是post!
核对需求发现有五处详情页列表的问题,跟原模式不太一样了,所以要重新构思,不过有了前面代码的铺垫,还是有点门路的
PS:这里要批评一下随意的需求!!!每当有问题,去跟需求核对,得到的解释大多是,这个不需要了???
WTF你知不知道,你看似一个简单的东西,很可能需要我们处理很久,解决很多的难点!!!尤其对于我这种实习生!太气人了!
所以需求必须做好,客户要的不能少,技术做的不能多,如果说需求做不到精确,团队的效率会下降,同时团队凝聚力也会受到很大的影响。
说回来项目:
三个列表页,有两个由我完成,剩下的一个由新来的实习生完成,不得不说赵薇喊这个人真的在这没经历敲代码的痛点,她的痛点主要集中在装软件
先说第一个,化妆品生产许可获证企业
首先这是一个目录页,而且需要翻页,那么F12查看网页源码,发现网页为post请求,ajax通信
通过post man 发送post请求,得到response响应
综上,思路清晰,直接代码
# -*- coding: utf-8 -*-
from seleniumrequests import Chrome
import json
from selenium import webdriver
from gjypjd.utils import *
def main():
option = None
mysql_db = DataBase()
# 配置文件中开启是否无头,生产阶段关闭
if if_headless():
option = webdriver.ChromeOptions()
option.add_argument(argument='headless')
option.add_argument('--no-sandbox')
for i in range(1, 330):
browser = Chrome(chrome_options=option)
url='http://125.35.6.84:81/xk/itownet/portalAction.do?method=getXkzsList&on=true&page=' + str(
i) + '&pageSize=15&productName=&conditionType=1&applyname=&applysn'
res = browser.request('post', url)
# print(res.text)
res1 = json.loads(res.content)['list']
# print(res1)
browser.close()
for j in range(len(res1)):
sql = "insert into t_hzpscxkhzqy_lbsj(c_bh, dt_insertTime, c_url, b_content, c_json,c_page) VALUES (REPLACE(UUID(),\"-\",\"\"), sysdate(), %s,%s,%s,%s)"
mysql_db.exetcute_sql(sql, [url, res.content, parse(res1[j]),
str(i) + '_' + str(j + 1)])
def parse(dic):
"""
企业名称qymc
许可证编号xkzbh
发证机关fzjg
有效期至yxqz
发证日期fzrq
"""
reg_dict = dict()
reg_dict['qymc'] = dic['EPS_NAME']
reg_dict['xkzbh'] = dic['PRODUCT_SN']
reg_dict['fzjg'] = dic['QF_MANAGER_NAME']
reg_dict['yxqz'] = dic['XK_DATE']
reg_dict['fzrq'] = dic['XC_DATE']
return json.dumps(reg_dict, ensure_ascii=False)
if __name__ == '__main__':
main()
直接得到要求的匹配字段,继续来看,我们需要爬取企业详情页信息,模式跟一级目录也相同
# -*- coding: utf-8 -*-
from seleniumrequests import Chrome
import json
from selenium import webdriver
from gjypjd.utils import *
def main():
option = None
mysql_db = DataBase()
# 配置文件中开启是否无头,生产阶段关闭
if if_headless():
option = webdriver.ChromeOptions()
option.add_argument(argument='headless')
option.add_argument('--no-sandbox')
for i in range(1, 330):
browser = Chrome(chrome_options=option)
url_1='http://125.35.6.84:81/xk/itownet/portalAction.do?method=getXkzsList&on=true&page=' + str(
i) + '&pageSize=15&productName=&conditionType=1&applyname=&applysn'
res1 = browser.request('post', url_1)
# print(res.text)
res1= json.loads(res1.content)['list']
# print(res1)
browser.close()
for j in range(len(res1)):
browser = Chrome(chrome_options=option)
url_2='http://125.35.6.84:81/xk/itownet/portalAction.do?method=getXkzsById&id='+res1[j]['ID']
res2 = browser.request('post', url_2)
res3 =json.loads(res2.content)
# print(res3)
browser.close()
sql = "insert into t_hzpscxkzhzqy_xkxq(c_bh, dt_insertTime, c_url, b_content, c_json,c_page) VALUES (REPLACE(UUID(),\"-\",\"\"), sysdate(), %s,%s,%s,%s)"
mysql_db.exetcute_sql(sql, [url_2, res2.content, parse(res3),
str(i) + '_' + str(j + 1)])
def parse(dic):
"""
企业名称qymc
许可证编号xkzbh
许可项目xkxm
企业住所qyzs
生产地址scdz
社会信用代码shxydm
法定代表人fddbr
企业负责人qyfzr
质量负责人zlfzr
发证机关fzjg
签发人qfr
日常监督管理机构rcjdgljg
日常监督管理人员rcjdglry
有效期至yxqz
发证日期fzrq
状态zt
投诉举报电话tsjbdh
"""
reg_dict = dict()
reg_dict['qymc'] = dic['epsName']
reg_dict['xkzbh'] = dic['productSn']
reg_dict['xkxm'] = dic['certStr']
reg_dict['qyzs'] = dic['epsAddress']
reg_dict['scdz'] = dic['epsProductAddress']
reg_dict['shxydm'] = dic['businessLicenseNumber']
reg_dict['fddbr'] = dic['legalPerson']
reg_dict['qyfzr'] = dic['businessPerson']
reg_dict['zlfzr'] = dic['qualityPerson']
reg_dict['fzjg'] = dic['qfManagerName']
reg_dict['qfr'] = dic['xkName']
reg_dict['rcjdgljg'] = dic['rcManagerDepartName']
reg_dict['rcjdglry'] = dic['rcManagerUser']
reg_dict['yxqz'] = dic['xkDate']
reg_dict['fzrq'] = dic['xkDateStr']
reg_dict['zt'] = '正常'
reg_dict['jbdh'] = '12331'
return json.dumps(reg_dict, ensure_ascii=False)
if __name__ == '__main__':
main()
很简单,没说什么问题
虽然同样为post请求,但是postman给出的response却是error,尝试传入参数来解决,发现postman的bug
尝试直接在代码中传入参数,发送post请求,传入headers和params,得到了JSON格式的响应
同时,在敲代码过程中,发现了数据动态更新,每天都会有批量数据的传入,所以翻页问题要传入动态参数,通过先发送post请求得到page参数
# -*- coding: utf-8 -*-
# 进口非特殊用途化妆品备案信息-备案详情
from seleniumrequests import Chrome
import json
from selenium import webdriver
import re
from gjypjd.utils import *
def main():
option = None
mysql_db = DataBase()
# 配置文件中开启是否无头,生产阶段关闭
if if_headless():
option = webdriver.ChromeOptions()
option.add_argument(argument='headless')
option.add_argument('--no-sandbox')
browser = Chrome(chrome_options=option)
url_1 = 'http://cpnp.nmpa.gov.cn/province/webquery/wq.do?method=query&querytype=productname&pfid=&content=&dataPage=0&perPage=15&allRows=8084&order='
response = browser.request('post', url_1)
response1 = json.loads(response.content)['pageBean']
page = response1['allPage']
browser.close()
for i in range(0, page):
browser = Chrome(chrome_options=option)
url_1='http://cpnp.nmpa.gov.cn/province/webquery/wq.do?method=query&querytype=productname&pfid=&content=&dataPage='+str(i)+'&allPage=539&perPage=15&allRows=8084&order='
res1 = browser.request('post', url_1)
res1= json.loads(res1.content)['list']
browser.close()
for j in range(len(res1)):
browser = Chrome(chrome_options=option)
url_2='http://cpnp.nmpa.gov.cn/province/webquery/wq.do?'
params = {'method': 'show','id':res1[j]['id']}
headers={
'Accept':'application/json, text/javascript, */*; q=0.01',
'Accept-Encoding':'gzip, deflate',
'Accept-Language':'zh-CN,zh;q=0.9',
'Connection':'keep-alive',
'Content-Length': '31',
'Content-Type':'application/x-www-form-urlencoded; charset=UTF-8',
'Cookie':'_gscu_515232071=60234697wnhvr115; _gscbrs_515232071=1; JSESSIONID=DA4CEE8CEE0F521678039F251D0A32AD',
'Host':'cpnp.nmpa.gov.cn',
'Origin':'http://cpnp.nmpa.gov.cn',
'Referer':'http://cpnp.nmpa.gov.cn/province/webquery/show.jsp?id=50BF34D2A36759BA',
'User-Agent':'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.90 Safari/537.36',
'X-Requested-With':'XMLHttpRequest'
}
res2 = browser.request('post', url_2, data=params, headers=headers)
browser.close()
sql = "insert into t_jkftsythzpbaxx_baxq(c_bh, dt_insertTime, c_url, b_content, c_json,c_page) VALUES (REPLACE(UUID(),\"-\",\"\"), sysdate(), %s,%s,%s,%s)"
mysql_db.exetcute_sql(sql, [url_2, res2.text, parse(json.loads(res2.text)),
str(i+1) + '_' + str(j+1)])
def parse(dic):
"""
产品名称cpmc
产品英文名称cpywm
备案编号babh
备案日期barq
生产企业名称(中文)scqymc_zw
生产企业名称(英文)scqymc_yw
生产企业地址scqydz
境内负责人名称jnfzrmc
境内负责人地址jnfzrdz
生产国(地区)scg_dq
进口省份jksf
成分cf
备注bz
备案资料核查bazlsc
历史ls
技术要求jsyq
产品设计包装平面图cpsjbzpmt
产品中文标签cpzwbq
产品上市包装立体图cpssbzltt
"""
s = re.findall('id=([0-9|A-Z]{16})', dic['preview'])
reg_dict = dict()
reg_dict['cpmc'] = dic['productname']
reg_dict['cpywm'] = dic['productnameen']
reg_dict['babh'] = dic['passno']
reg_dict['barq'] = dic['passdate']
reg_dict['scqymc_zw'] = dic['enterprise']
reg_dict['scqymc_yw'] = dic['enterpriseen']
reg_dict['scqydz'] = dic['enterpriseaddressen']
reg_dict['jnfzrmc'] = dic['internalunitname']
reg_dict['jnfzrdz'] = dic['internalunitaddr']
reg_dict['scg_dq'] = dic['Country']
reg_dict['jksf'] = dic['jksf']
reg_dict['cf'] = dic['cf']
reg_dict['bz'] = dic['memo']
reg_dict['bazlsc'] = dic['CheckupResult']
reg_dict['ls'] = dic['hisList']
reg_dict['jsyq'] = 'http://cpnp.nmpa.gov.cn/province/webquery/wq.do?method=jsyq&id='+s[0]
reg_dict['cpsjbzpmt'] = 'http://cpnp.nmpa.gov.cn/province/webquery/preview.jsp?id='+s[1]
reg_dict['cpzwbq'] = 'http://cpnp.nmpa.gov.cn/province/webquery/preview.jsp?id='+s[2]
reg_dict['cpssbzltt'] = 'http://cpnp.nmpa.gov.cn/province/webquery/preview.jsp?id='+s[3]
return json.dumps(reg_dict, ensure_ascii=False)
if __name__ == '__main__':
main()
基本项目到此真的结束,剩下的就是根据需求反馈,调整未得到的数据,做一个一段时间的维护