CFDA
cfda数据抓取
1.网站数据是加密的,需要浏览器进行数据解析
2.网址url有js加密
3.PhantomJS无法解析数据, chrome无法获取数据,所有最终选择用Firefox浏览器
import pymysql
import time
import uuid
from lxml import etree
import logging
from selenium import webdriver
import threading
import queue
import re logging.basicConfig(filename='shengchan.log', filemode="w", level=logging.INFO) class App1Spider(object):
def __init__(self):
self.db = pymysql.connect(host='', port=, database='', user='',
password='', charset='utf8')
self.cursor = self.db.cursor()
self.options = webdriver.FirefoxOptions()
self.options.add_argument('--headless')
# 谷歌文档提到需要加上这个属性来规避bug
self.options.add_argument('--disable-gpu')
# 设置默认编码为utf-8
self.options.add_argument('lang=zh_CN.UTF-8')
# 隐藏滚动条, 应对一些特殊页面
self.options.add_argument('--hide-scrollbars')
# 禁止加载图片
self.options.add_argument('blink-settings=imagesEnabled=false')
# 指定浏览器分辨率
self.options.add_argument('window-size=1440x900')
self.browser = webdriver.Firefox(firefox_options=self.options) def main(self):
"""
入口函数
:param response:
:return:
"""
start = 1
while True:
browser = self.go_index()
if browser:
for i in range(start, 520):
browser = self.go_page(browser, i)
if browser:
for j in range(15):
if i > 511:
detail_html = self.go_detail(browser, j)
if detail_html:
id = (i - 1) * 15 + j + 1
self.parse_detail(detail_html, id)
else:
break
else:
start = i - 1
break
else:
continue def go_index(self):
"""
访问主页
:return: 浏览器对象
"""
# print("!-- start index --!")
index_url = "http://app1.sfda.gov.cn/datasearch/face3/base.jsp?tableId=34&tableName=TABLE34&title=%D2%A9%C6%B7%C9%FA%B2%FA%C6%F3%D2%B5&bcId=118103348874362715907884020353"
try:
self.browser.get(index_url)
time.sleep(3)
except:
# print("!-- error to get index page --!")
# print("网速不太好,休息1分钟")
time.sleep(30)
return None
else:
html = self.browser.page_source
condition = re.search(r"管理局--数据查询", html)
if condition:
# print("!-- success to get index page --!")
return self.browser
else:
# print("!-- error to get index page --!----")
# print("网速不太好,休息1分钟------")
time.sleep(30)
return None def go_page(self, browser, page):
"""
跳转到指定页面
:param browser: 浏览器对象
:param page: 要跳转的页码
:return: 跳转后的浏览器对象
"""
# logging.info("!-- start page %s --!" % page)
print("!-- start page %s --!" % page)
go_page_js = 'location.href="javascript:devPage(%s)";' % page
try:
browser.execute_script(go_page_js)
# 需要等待firefox页面加载完成
time.sleep(2)
except Exception as e:
print("!-- error to go page %s --!" % page)
# logging.info("!-- error to go page %s --!" % page)
return None
else:
html = browser.page_source
condition = re.search(r"第 %s 页" % page, html)
if condition:
logging.info("!-- success to go page %s --!" % page)
return browser
else:
logging.info("!-- error to go page %s --!" % page)
return None def go_detail(self, browser, number):
"""
包含了提取详情页面数据信息,保存数据信息。
:param browser: 浏览器对象
:return: 详细数据生成器
"""
# logging.info("!-- go detail %s --!" % number)
print("!-- go detail %s --!" % number)
go_detail_js = "var div=document.getElementById('content');" \
"var c=div.getElementsByTagName('a')[{detail_num}].click();"
return_list_js = 'location.href = "javascript:viewList();"'
_go_detail_js = go_detail_js.format(detail_num=number)
browser.execute_script(_go_detail_js)
time.sleep(2)
detail_html = browser.page_source
condition = re.search(r"javascript:viewList", detail_html)
if condition:
browser.execute_script(return_list_js)
time.sleep(2)
return detail_html
else:
# logging.info("!-- error to get detail --! %s" % number)
print("!-- error to get detail --! %s" % number)
return None def parse_detail(self, detail_html, id):
# print(id)
"""
详情页面提取规则
:param html: 被提取页面的html
:return: data
"""
response = etree.HTML(detail_html) try:
# 厂家编号
number = response.xpath('//*[@id="content"]/div/div/table[1]/tbody/tr[2]/td[2]/text()')[0].strip().replace("'", "‘")
except:
number = '00000000' try:
# 生产地址
manufactureAddress = response.xpath('//*[@id="content"]/div/div/table[1]/tbody/tr[11]/td[2]/text()')[0].strip().replace("'", "‘")
except:
manufactureAddress = '' try:
# 生产范围
manufactureRange = response.xpath('//*[@id="content"]/div/div/table[1]/tbody/tr[12]/td[2]/text()')[0].strip().replace("'", "‘")
except:
manufactureRange = '' try:
# 发证日期
certificateDate = response.xpath('//*[@id="content"]/div/div/table[1]/tbody/tr[13]/td[2]/text()')[0].strip().replace("'", "‘")
except:
certificateDate = '2018-01-01' try:
# 有效期
validityDate = response.xpath('//*[@id="content"]/div/div/table[1]/tbody/tr[14]/td[2]/text()')[0].strip().replace("'", "‘")
except:
validityDate = '2018-01-01' try:
# 发证机关
certificateOrgan = response.xpath('//*[@id="content"]/div/div/table[1]/tbody/tr[15]/td[2]/text()')[0].strip().replace("'", "‘")
except:
certificateOrgan = '' try:
# 签发人
Signer = response.xpath('//*[@id="content"]/div/div/table[1]/tbody/tr[16]/td[2]/text()')[0].strip().replace("'", "‘")
except:
Signer = '' try:
# 日常监管机构
superviseAgency = response.xpath('//*[@id="content"]/div/div/table[1]/tbody/tr[17]/td[2]/text()')[0].strip().replace("'", "‘")
except:
superviseAgency = '' try:
# 日常监管人员
superviser = response.xpath('//*[@id="content"]/div/div/table[1]/tbody/tr[18]/td[2]/text()')[0].strip().replace("'", "‘")
except:
superviser = '' try:
# 社会信用代码/组织机构代码
socialCreditCode = response.xpath('//*[@id="content"]/div/div/table[1]/tbody/tr[3]/td[2]/text()')[0].strip().replace("'", "‘")
except:
socialCreditCode = '' try:
# 监督举报电话
reportTel = response.xpath('//*[@id="content"]/div/div/table[1]/tbody/tr[19]/td[2]/text()')[0].strip().replace("'", "‘")
except:
reportTel = '' try:
# 备注
comment = response.xpath('//*[@id="content"]/div/div/table[1]/tbody/tr[20]/td[2]/text()')[0].strip().replace("'", "‘")
except:
comment = '' try:
# 分类码
classificationCode = response.xpath('//*[@id="content"]/div/div/table[1]/tbody/tr[4]/td[2]/text()')[0].strip().replace("'", "‘")
except:
classificationCode = '' try:
# 省份
province = response.xpath('//*[@id="content"]/div/div/table[1]/tbody/tr[5]/td[2]/text()')[0].strip().replace("'", "‘")
except:
province = '' try:
# 企业名称
companyName = response.xpath('//*[@id="content"]/div/div/table[1]/tbody/tr[6]/td[2]/text()')[0].strip().replace("'", "‘")
except:
companyName = '' try:
# 法定代表人
legalPeople = response.xpath('//*[@id="content"]/div/div/table[1]/tbody/tr[7]/td[2]/text()')[0].strip().replace("'", "‘")
except:
legalPeople = '' try:
# 企业负责人
companyResponsioner = response.xpath('//*[@id="content"]/div/div/table[1]/tbody/tr[8]/td[2]/text()')[0].strip().replace("'", "‘")
except:
companyResponsioner = '' try:
# 质量负责人
qualityResponsioner = response.xpath('//*[@id="content"]/div/div/table[1]/tbody/tr[9]/td[2]/text()')[0].strip().replace("'", "‘")
except:
qualityResponsioner = '' try:
# 注册地址
registerAddress = response.xpath('//*[@id="content"]/div/div/table[1]/tbody/tr[10]/td[2]/text()')[0].strip().replace("'", "‘")
except:
registerAddress = '' cjrepetition = self.cursor.execute("select id from cfda_drug_company20181205 where numbers = %s" % id)
if not cjrepetition:
cjsql = "insert into cfda_drug_company20181205(number, manufactureAddress, manufactureRange, certificateDate, validityDate, certificateOrgan, Signer, superviseAgency, superviser, socialCreditCode, reportTel, comment, classificationCode, province, companyName, legalPeople, companyResponsioner, qualityResponsioner, registerAddress, numbers) values('{}', '{}', '{}', '{}', '{}', '{}', '{}', '{}', '{}', '{}', '{}', '{}', '{}', '{}', '{}', '{}', '{}', '{}', '{}', {})"
cjsql_data = cjsql.format(number, manufactureAddress, manufactureRange,
certificateDate, validityDate, certificateOrgan,
Signer, superviseAgency, superviser,
socialCreditCode, reportTel, comment,
classificationCode, province, companyName,
legalPeople, companyResponsioner, qualityResponsioner,
registerAddress, int(id))
try:
self.cursor.execute(cjsql_data)
self.db.commit()
except Exception as e:
print('id:%s e:%s' % (id, e)) if __name__ == '__main__':
sheng = App1Spider()
sheng.main()
CFDA的更多相关文章
- JS base64 加密和 后台 base64解密(防止中文乱码)
直接上代码 1,js(2个文件,网上找的) 不要觉的长,直接复制下来就OK //UnicodeAnsi.js文件 //把Unicode转成Ansi和把Ansi转换成Unicode function ...
- OpenGL阴影,Shadow Volumes(附源程序,使用 VCGlib )
实验平台:Win7,VS2010 先上结果截图: 本文是我前一篇博客:OpenGL阴影,Shadow Mapping(附源程序)的下篇,描述两个最常用的阴影技术中的第二个,Shadow Volu ...
- C++ stringstream
C++ 引入了ostringstream.istringstream.stringstream这三个类,这三个类包含在sstream.h头文件中.三个类中 1)istringstream类用于执行C+ ...
- 基于nodejs实现js后端化处理
今天D哥给我提了个问题,"用php执行过js没"?咋一听,没戏~~毕竟常规情况下,js是依赖浏览器运行的.想在php后端采集的同时利用js运行结果并传递给php使用,没戏! 然后回 ...
- uva 10129 play on words——yhx
aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAABNUAAANeCAYAAAA1BjiHAAAgAElEQVR4nOydabWsuhaFywIasIAHJK
- 第一部分 CLR基础:第2章 生成、打包、部署和管理应用程序及类型
2.1.NET Framework部署目标 Microsoft Windows多年来因不稳定和复杂而口碑不佳.造成的原因:1.应用程序都使用来自微软和厂商的动态链接库(dynamic-link lib ...
- Michael Kors - Wikipedia, the free encyclopedia
Michael Kors - Wikipedia, the free encyclopedia Michael Kors From Wikipedia, the free encyclopedia ...
- Html5模拟通讯录人员排序(sen.js)
// JavaScript Document var PY_Json_Str = ""; var PY_Str_1 = ""; var PY_Str_2 = & ...
- 爬虫之scrapy-redis
redis分布式部署 scrapy框架是否可以自己实现分布式? 不可以原因有两点 其一:因为多台机器上部署的scrapy会各自拥有各自的调度器,这样就使得多台机器无法分配start_urls列表中的u ...
随机推荐
- 皮卡丘检测器-CNN目标检测入门教程
目标检测通俗的来说是为了找到图像或者视频里的所有目标物体.在下面这张图中,两狗一猫的位置,包括它们所属的类(狗/猫),需要被正确的检测到. 所以和图像分类不同的地方在于,目标检测需要找到尽量多的目标物 ...
- python学习之----lxml库和HTML parser
lxml 这个库(http://lxml.de/)可以用来解析HTML 和XML 文档,以非常底层的实现而闻名 于世,大部分源代码是用C 语言写的.虽然学习它需要花一些时间(其实学习曲线越 陡峭,表明 ...
- FastDFS 配置 Nginx 模块,并实现分布式同步-Linux
1.搭建虚拟机 a.复制虚拟机文件 首先复制我们之前安装好的fastdfs虚拟机,因为我们现在要设置它的IP为21,改名为CentOS-fastdfs - 21. b.设置网络 生成新的MAC地址 设 ...
- mysql中表里的数据重新设置自增的id的方法
如果删除表数据用这个 TRUNCATE TABLE tablename 如果不删除表 alter table table_name AUTO_INCREMENT=;
- 13.纯 CSS 创作一个冒着热气的咖啡杯
原文地址:https://segmentfault.com/a/1190000014734039 感想:伪元素::before ::after 真的很强大,动画也是. HTML代码: <div ...
- angular.js前端分层开发(页面和js代码分离,并将js代码分层)
一. 抽取模块成base.js文件// 定义模块: var app = angular.module("eshop",['pagination']); 二. 抽取服务成brandS ...
- Android悬浮窗及其拖动事件
主页面布局很简单,只有一个RelativelyLayout <?xml version="1.0" encoding="utf-8"?> <R ...
- django之urlresolver
>>> from django.utils.regex_helper import normalize >>> bits=normalize(r'^static/( ...
- ARP 欺骗攻击与防御
<一> ARP攻防 理论 和 工具 工具: 01: Wireshark ( 抓包软件 ) 02: P2P终结者 ( ARP欺骗工具 ) 03: cain & abel ( ...
- jmap dump文件压缩后失效
最近线上出问题,于是用jmap -dump拿到dump文件,再linux压缩后拿到windows下无效,后来又直接拿了一个没有压缩的竟然可以用...坑啊!~