
档案系统初期算是告一段落了,利用一点时间继续爬取POI。和领导聊聊,受益匪浅。之前我的想法是爬取一份poi数据,直接能用;而领导听了之后,觉得更好的方式是爬取多个渠道来源的POI数据,然后做一个数据比较融合(最终事情能不能成不好说,但是经过这么一回,细节技术上有所提高,宏观把控整体项目流程能力有所长进,更重要的是通过和能人交流,以更高的眼界更宏观的看待数据、应用以及问题,这就是成长)。 我之前采用的方式,可以满足需求,但是POI数据获取效率差一些(虽然已经很快,但是相比本文这种还是慢一些)、数据现势性不好,高德数据和百度数据虽然是两套,但是仅仅是坐标不同(所以显然还是一套)。所以,我加一种方式来爬取百度poi。
一 调研: 百度API提供了一个叫Place API获取poi的接口,有个城市内检索 实例为
ce/v2/searchquery=银行&page_size=10&page_num=0&scope=1®ion=北京&output=json&ak={您的密钥}
它返回的是个json类型数据,一个区域最大返回数为400,每页最大返回数为20。显然一个城市内不管什么类别的poi,不可能只有400个,会遗漏数据,故舍去
还有一个矩形区域检索,实例为
ucom/place/v2/searchquery=美食&page_size=10&page_num=0&scope=1&bounds=39915,116404,39975,116414&output=json&ak={您的密钥}只要区域划分得当,这个可以使用
二 要解决的问题
1 区域划分
网上有人通过递归写代码的方式来划分,这样划分有问题,第一,划分的区域不能完全对应一个城市的市区;第二,算法设计比较麻烦。解决办法,后面详细说。
2 类别问题
百度API的接口必须要指定query的类别,那么如果类别指定不准,或者类别不全,根本无法完成爬取一个城市所有poi的任务。解决办法,说实话,这个问题在我做这件事情的时候,
十分棘手,不过我最终找到了这个网页
/indexphptitle=lbscloud/poitags,一切都不是问题了
三 整体流程
1 区域划分,2km2km的区域基本可以满足需求,获取每个区域的对角坐标(经纬度),逐行写入一个txt文本里
2 爬虫程序编写 读取1中的txt文本,逐行循环;调用百度API接口,爬取json;将爬取的数据存入数据库中; 每个类别跑一次程序
3 爬下的POI数据处理 poi显示,投影坐标转换,与地图叠加
后文将详细介绍流程
一、首先理解下面几个函数
设置变量 length()函数 char_length() replace() 函数 max() 函数
11、设置变量 set @变量名=值
set @address='中国-山东省-聊城市-莘县';select @address
12 、length()函数 char_length()函数区别
select length('a')
,char_length('a')
,length('中')
,char_length('中')
13、 replace() 函数 和length()函数组合
set @address='中国-山东省-聊城市-莘县';select @address
,replace(@address,'-','') as address_1
,length(@address) as len_add1
,length(replace(@address,'-','')) as len_add2
,length(@address)-length(replace(@address,'-','')) as _count
etl清洗字段时候有明显分割符的如何确定新的数据表增加几个分割出的字段
计算出com_industry中最多有几个 - 符 以便确定增加几个字段 最大值+1 为可以拆分成的字段数 此表为3 因此可以拆分出4个行业字段 也就是4个行业等级
select max(length(com_industry)-length(replace(com_industry,'-',''))) as _max_count
from etl1_socom_data
14、设置变量 substring_index()字符串截取函数用法
set @address='中国-山东省-聊城市-莘县';
select
substring_index(@address,'-',1) as china,
substring_index(substring_index(@address,'-',2),'-',-1) as province,
substring_index(substring_index(@address,'-',3),'-',-1) as city,
substring_index(@address,'-',-1) as district
15、条件判断函数 case when
case when then when then else 值 end as 字段名
select case when 89>101 then '大于' else '小于' end as betl1_socom_data
二、kettle转换etl1清洗
首先建表 步骤在视频里
字段索引 没有提 索引算法建议用BTREE算法增强查询效率
21kettle文件名:trans_etl1_socom_data
22包括控件:表输入>>>表输出
23数据流方向:s_socom_data>>>>etl1_socom_data
kettle转换1截图
24、表输入24、SQL脚本 初步清洗com_district和com_industry字段
select a,case when com_district like '%业' or com_district like '%织' or com_district like '%育' then null else com_district end as com_district1
,case when com_district like '%业' or com_district like '%织' or com_district like '%育' then concat(com_district,'-',com_industry) else com_industry end as com_industry_total
,replace(com_addr,'地 址:','') as com_addr1
,replace(com_phone,'电 话:','') as com_phone1
,replace(com_fax,'传 真:','') as com_fax1
,replace(com_mobile,'手机:','') as com_mobile1
,replace(com_url,'网址:','') as com_url1
,replace(com_email,'邮箱:','') as com_email1
,replace(com_contactor,'联系人:','') as com_contactor1
,replace(com_emploies_nums,'公司人数:','') as com_emploies_nums1
,replace(com_reg_capital,'注册资金:万','') as com_reg_capital1
,replace(com_type,'经济类型:','') as com_type1
,replace(com_product,'公司产品:','') as com_product1
,replace(com_desc,'公司简介:','') as com_desc1from s_socom_data as a
25、表输出
表输出设置注意事项
注意事项:
① 涉及爬虫增量 *** 作 不要勾选裁剪表选项
②数据连接问题 选择表输出中表所在的数据库
③字段映射问题 确保数据流中的字段和物理表的字段数量一致 对应一致
三、kettle转换etl2清洗
首先建表增加了4个字段 演示步骤在视频里
字段索引 没有提 索引算法建议用BTREE算法增强查询效率
主要针对etl1 生成的新的com_industry进行字段拆分 清洗
31kettle文件名:trans_etl2_socom_data
32包括控件:表输入>>>表输出
33数据流方向:etl1_socom_data>>>>etl2_socom_data
注意事项:
① 涉及爬虫增量 *** 作 不要勾选裁剪表选项
②数据连接问题 选择表输出中表所在的数据库
③字段映射问题 确保数据流中的字段和物理表的字段数量一致 对应一致
kettle转换2截图
34、SQL脚本 对com_industry进行拆分 完成所有字段清洗 注册资金字段时间关系没有进行细致拆解 调整代码即可
select a,case
#行业为''的值 置为空when length(com_industry)=0 then null
#其他的取第一个-分隔符之前else substring_index(com_industry,'-',1) end as com_industry1,case
when length(com_industry)-length(replace(com_industry,'-',''))=0 then null
#'交通运输、仓储和邮政业-' 这种值 行业2 也置为nullwhen length(com_industry)-length(replace(com_industry,'-',''))=1 and length(substring_index(com_industry,'-',-1))=0 then nullwhen length(com_industry)-length(replace(com_industry,'-',''))=1 then substring_index(com_industry,'-',-1)else substring_index(substring_index(com_industry,'-',2),'-',-1)end as com_industry2,case
when length(com_industry)-length(replace(com_industry,'-',''))<=1 then nullwhen length(com_industry)-length(replace(com_industry,'-',''))=2 then substring_index(com_industry,'-',-1)else substring_index(substring_index(com_industry,'-',3),'-',-1)end as com_industry3,case
when length(com_industry)-length(replace(com_industry,'-',''))<=2 then nullelse substring_index(com_industry,'-',-1)end as com_industry4from etl1_socom_data as a
四、清洗效果质量检查
41爬虫数据源数据和网站数据是否相符
如果本身工作是爬虫和数据处理在一起处理,抓取的时候其实已经判断,此步骤可以省略,如果对接上游爬虫同事,这一步首先判断,不然清洗也是无用功,一般都要求爬虫同事存储请求的url便于后面数据处理查看数据质量
42计算爬虫数据源和各etl清洗数据表数据量
注:SQL脚本中没有经过聚合过滤 3个表数据量应相等
421、sql查询 下面表我是在同一数据库中 如果不在同一数据库 from 后面应加上表所在的数据库名称
不推荐数据量大的时候使用
select count(1) from s_socom_dataunion all
select count(1) from etl1_socom_dataunion all
select count(1) from etl2_socom_data
422 根据 kettle转换执行完毕以后 表输出总量对比
kettle表输出总数据量
43查看etl清洗质量
确保前两个步骤已经无误,数据处理负责的etl清洗工作自查开始 针对数据源清洗的字段 写脚本检查 socom网站主要是对地区 和行业进行了清洗 对其他字段做了替换多余字段处理 ,因此采取脚本检查,
找到page_url和网站数据进行核查
where里面这样写便于查看某个字段的清洗情况
select
from etl2_socom_data
where com_district is null and length(com_industry)-length(replace(com_industry,'-',''))=3
此页面数据和etl2_socom_data表最终清洗数据对比
网站页面数据
etl2_socom_data表数据
清洗工作完成。
我举个例子你照着改吧
import requests
url = ">
你看的那个网上解释,不准确的。
jsonloads是将json对象转成原生对象。。。也就是说,原来是啥对象,就能给你转出来。只是数据类型,json只支持str类型。如果你原来的对象是dict类型,当然可以用datakeys()方法。但既然错误提示你的事原来的对象是str。。。
1win10 下 win + r 打开cmd 切换新项目的目录
2新建scrapy项目的命令:
可以利用pycharm 打开项目文件夹编辑项目
3itemspy
声明爬取的字段
4新建scrapy 爬虫
用命令 scrapy genspider doubanmovie "moviedoubancom" 创建爬虫。
5运行爬虫
51 创建运行脚本
(一)、在 scrapycfg 同级目录下创建 pycharm 调试脚本 runpy,避免每次运行爬虫输入密码,内容如下:
6修改robottxt协议
修改 settings 中的 ROBOTSTXT_OBEY = True 参数为 False,因为默认为 True,就是要遵守 robotstxt 的规则, robotstxt 是遵循 Robot协议 的一个文件,它保存在网站的服务器中,它的作用是,告诉搜索引擎爬虫,本网站哪些目录下的网页不希望你进行爬取收录。在 Scrapy 启动后,会在第一时间访问网站的 robotstxt 文件,然后决定该网站的爬取范围。查看 robotstxt 可以直接网址后接 robotstxt 即可。
一般构建爬虫系统,建议自己编写Item Pipeline,就可以在open(path)选择自己的保存路径
参考: # scrapy爬虫事件以及数据保存为txt,json,mysql
71保存为json格式时出现乱码的解决方式:
scrapy抓取豆瓣书籍保存json文件乱码问题
中文默认是Unicode,如:
\u5317\u4eac\u5927\u5b66
在setting文件settingspy中设置:
就可以解决了
第二种解决办法
或在cmd中传入 -s FEED_EXPORT_ENCODING='utf-8'
参考: >
MySQL
是一个关系型数据库管理系统,由瑞典MySQLAB公司开发,目前属于Oracle旗下产品。MySQL是最流行的关系型数据库管理系统之一,在WEB应用方面,MySQL是最好的RDBMS(RelationalDatabaseManagementSystem,关系数据库管理系统)应用软件。
MySQL是一种关系数据库管理系统,关系数据库将数据保存在不同的表中,而不是将所有数据放在一个大仓库内,这样就增加了速度并提高了灵活性。
MySQL所使用的SQL语言是用于访问数据库的最常用标准化语言。MySQL软件采用了双授权政策,分为社区版和商业版,由于其体积小、速度快、总体拥有成本低,尤其是开放源码这一特点,一般中小型网站的开发都选择MySQL作为网站数据库。
:《Python基础教程》
应用环境
与其他的大型数据库例如Oracle、DB2、SQLServer等相比,MySQL自有它的不足之处,但是这丝毫也没有减少它受欢迎的程度。对于一般的个人使用者和中小型企业来说,MySQL提供的功能已经绰绰有余,而且由于MySQL是开放源码软件,因此可以大大降低总体拥有成本。
MongoDB
是一个基于分布式文件存储的数据库。由C语言编写。旨在为WEB应用提供可扩展的高性能数据存储解决方案。
MongoDB是一个介于关系数据库和非关系数据库之间的产品,是非关系数据库当中功能最丰富,最像关系数据库的。它支持的数据结构非常松散,是类似json的bson格式,因此可以存储比较复杂的数据类型。Mongo最大的特点是它支持的查询语言非常强大,其语法有点类似于面向对象的查询语言,几乎可以实现类似关系数据库单表查询的绝大部分功能,而且还支持对数据建立索引。
特点
它的特点是高性能、易部署、易使用,存储数据非常方便。主要功能特性有:
面向集合存储,易存储对象类型的数据。
mongodb集群参考
模式自由。
支持动态查询。
支持完全索引,包含内部对象。
支持查询。
支持复制和故障恢复。
使用高效的二进制数据存储,包括大型对象(如视频等)。
自动处理碎片,以支持云计算层次的扩展性。
支持RUBY,PYTHON,JAVA,C,PHP,C#等多种语言。
文件存储格式为BSON(一种JSON的扩展)。
可通过网络访问。
以上就是关于怎么使用python爬取百度网的数据全部的内容,包括:怎么使用python爬取百度网的数据、Python爬虫数据应该怎么处理、python爬虫post请求中的data参数怎么接受json格式的list等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)