使用python爬取东方财富网机构调研数据

  最近有一个需求,需要爬取东方财富网的机构调研数据.数据所在的网页地址为: 机构调研

  网页如下所示:

  

  可见数据共有8464页,此处不能直接使用scrapy爬虫进行爬取,因为点击下一页时,浏览器只是发起了javascript网络访问,然后将服务器返回的数据插入网页,无法通过网址直接获取对应页的的页面数据.

  通过chrome的开发者工具,我们可以看到点击下一页按钮背后发起的网页访问:

  在点击下一页时,浏览器向地址发起了访问.我们分析一下这个地址的结构:

    http://data.eastmoney.com/DataCenter_V3/jgdy/xx.ashx?pagesize=50&page=2&js=var%20ZUPcjFOK&param=&sortRule=-1&sortType=0&rt=48759234

  上述地址中的&page=  之后指定的是需要获取第几个页面的数据.所以我们可以通过修改&page=后面的数字来访问不同页面对应的数据.

  现在看一下这个数据的结构:

  可见这个数据是一个字符串,根据第一个出现的等于号对该字符串进行切分,切分得到的后半段是一个json字符串,里面存储了我们想要获取的数据. json数据中的字段pages的值就是页面的总数.根据这一特性我们可以写出下述函数获取页面的总数:

# 获取页数
def get_pages_count():url = '''http://data.eastmoney.com/DataCenter_V3/jgdy/xx.ashx?pagesize=50&page=%d''' % 1url += "&js=var%20ngDoXCbV&param=&sortRule=-1&sortType=0&rt=48753724"wp = urllib.urlopen(url)data = wp.read().decode("gbk")start_pos = data.index('=')json_data = data[start_pos + 1:]dict = json.loads(json_data)pages =dict['pages']return pages

  在给定页数范围的情况下可以获取数据地址列表,如下所示:

# 获取链接列表
def get_url_list(start,end):url_list=[]while(start<=end):url = '''http://data.eastmoney.com/DataCenter_V3/jgdy/xx.ashx?pagesize=50&page=%d''' %starturl += "&js=var%20ngDoXCbV&param=&sortRule=-1&sortType=0&rt=48753724"url_list.append(url)start+=1return url_list

  为了保存这些数据,我使用sqlalchemy中的orm模型来表示数据模型,数据模型定义如下:

# 此处需要设置charset,否则中文会乱码
engine =create_engine('mysql+mysqldb://user:passwd@ip:port/db_name?charset=utf8')
Base =declarative_base()class jigoudiaoyan(Base):__tablename__ = "jigoudiaoyan"# 自增的主键id =Column(Integer,primary_key=True)# 调研日期StartDate = Column(Date,nullable=True)# 股票名称SName =Column(VARCHAR(255),nullable=True)# 结束日期 一般为空EndDate=Column(Date,nullable=True)# 接待方式Description =Column(VARCHAR(255),nullable=True)# 公司全称CompanyName =Column(VARCHAR(255),nullable=True)# 结构名称OrgName=Column(VARCHAR(255),nullable=True)# 公司代码CompanyCode=Column(VARCHAR(255),nullable=True)# 接待人员Licostaff=Column(VARCHAR(800),nullable=True)# 一般为空 意义不清OrgSum=Column(VARCHAR(255),nullable=True)# 涨跌幅ChangePercent=Column(Float,nullable=True)# 公告日期NoticeDate=Column(Date,nullable=True)# 接待地点Place=Column(VARCHAR(255),nullable=True)# 股票代码SCode=Column(VARCHAR(255),nullable=True)# 结构代码OrgCode=Column(VARCHAR(255),nullable=True)# 调研人员Personnel=Column(VARCHAR(255),nullable=True)# 最新价Close=Column(Float,nullable=True)#机构类型OrgtypeName=Column(VARCHAR(255),nullable=True)# 机构类型代码Orgtype=Column(VARCHAR(255),nullable=True)# 主要内容,一般为空 意义不清Maincontent=Column(VARCHAR(255),nullable=True)
Session =sessionmaker(bind=engine)
session =Session()
# 创建表
Base.metadata.create_all(engine)
# 获取链接列表

  在上述基础上,我们就可以定义下属函数用于抓取链接的内容,并将其解析之后存入数据库,如下所示:

#记录并保存数据
def save_json_data(user_agent_list):pages =get_pages_count()
len_user_agent=len(user_agent_list)url_list
=get_url_list(1,pages)count=0for url in url_list:request = urllib2.Request(url)request.add_header('Referer','http://data.eastmoney.com/jgdy/')# 随机从user_agent池中取userpos =random.randint(0,len_user_agent-1)request.add_header('User-Agent', user_agent_list[pos])reader = urllib2.urlopen(request)data=reader.read()# 自动判断编码方式并进行解码encoding = chardet.detect(data)['encoding']# 忽略不能解码的字段data = data.decode(encoding,'ignore')start_pos = data.index('=')json_data = data[start_pos + 1:]dict = json.loads(json_data)list_data = dict['data']count+=1for item in list_data:one = jigoudiaoyan()StartDate =item['StartDate'].encode("utf8")if(StartDate ==""):StartDate = Noneelse:StartDate = datetime.datetime.strptime(StartDate,"%Y-%m-%d").date()SName=item['SName'].encode("utf8")if(SName ==""):SName =NoneEndDate = item["EndDate"].encode("utf8")if(EndDate==""):EndDate=Noneelse:EndDate=datetime.datetime.strptime(EndDate,"%Y-%m-%d").date()Description=item['Description'].encode("utf8")if(Description ==""):Description= NoneCompanyName=item['CompanyName'].encode("utf8")if(CompanyName==""):CompanyName=NoneOrgName=item['OrgName'].encode("utf8")if(OrgName ==""):OrgName=NoneCompanyCode=item['CompanyCode'].encode("utf8")if(CompanyCode==""):CompanyCode=NoneLicostaff=item['Licostaff'].encode("utf8")if(Licostaff ==""):Licostaff=NoneOrgSum = item['OrgSum'].encode("utf8")if(OrgSum ==""):OrgSum=NoneChangePercent=item['ChangePercent'].encode("utf8")if(ChangePercent ==""):ChangePercent=Noneelse:ChangePercent=float(ChangePercent)NoticeDate=item['NoticeDate'].encode("utf8")if(NoticeDate==""):NoticeDate=Noneelse:NoticeDate=datetime.datetime.strptime(NoticeDate,"%Y-%m-%d").date()Place=item['Place'].encode("utf8")if(Place==""):Place=NoneSCode=item["SCode"].encode("utf8")if(SCode==""):SCode=NoneOrgCode=item['OrgCode'].encode("utf8")if(OrgCode==""):OrgCode=NonePersonnel=item['Personnel'].encode('utf8')if(Personnel==""):Personnel=NoneClose=item['Close'].encode("utf8")if(Close==""):Close=Noneelse:Close =float(Close)OrgtypeName =item['OrgtypeName'].encode("utf8")if(OrgtypeName==""):OrgtypeName=NoneOrgtype=item['Orgtype'].encode("utf8")if(Orgtype==""):Orgtype=NoneMaincontent=item['Maincontent'].encode("utf8")if(Maincontent==""):Maincontent=Noneone.StartDate=StartDateone.SName=SNameone.EndDate=EndDateone.Description=Descriptionone.CompanyName=CompanyNameone.OrgName=OrgNameone.CompanyCode=CompanyCodeone.Licostaff=Licostaffone.OrgSum=OrgSumone.ChangePercent=ChangePercentone.NoticeDate=NoticeDateone.Place=Placeone.SCode=SCodeone.OrgCode=OrgCodeone.Personnel=Personnelone.Close=Closeone.OrgtypeName=OrgtypeNameone.Orgtype=Orgtypeone.Maincontent=Maincontentsession.add(one)session.commit()print 'percent:' ,count*1.0/pages,"complete!,now ",count# delay 1stime.sleep(1)

  为了加快抓取速度,我设置了user_agent池,每次访问设置user_agent时随机从池中取一条作为这次访问的user_agent.对应列表user_agent_list ,定义如下:

# user_agent 池
user_agent_list=[]
user_agent_list.append("Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_8; en-us) AppleWebKit/534.50 (KHTML, like Gecko) Version/5.1 ")
user_agent_list.append("Mozilla/5.0 (Windows; U; Windows NT 6.1; en-us) AppleWebKit/534.50 (KHTML, like Gecko) Version/5.1 Safari/534.50")
user_agent_list.append("Mozilla/5.0 (Macintosh; Intel Mac OS X 10.6; rv:2.0.1) Gecko/20100101 Firefox/4.0.1")
user_agent_list.append("Opera/9.80 (Macintosh; Intel Mac OS X 10.6.8; U; en) Presto/2.8.131 Version/11.11")
user_agent_list.append("Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_0) AppleWebKit/535.11 (KHTML, like Gecko) Chrome/17.0.963.56 ")
user_agent_list.append("Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/48.0.2564.116 Safari/537.36")

  请注意,为了自动识别网页编码并解码,我使用了chardet模块识别网页的编码.为了应对极端情况下解码失败的问题,我在解码时设置跳过那些不能正确解码的字符串.相关代码截取如下:

 encoding = chardet.detect(data)['encoding']# 忽略不能解码的字段data = data.decode(encoding,'ignore') 

补充:

  网址中最后一个字段代码时间戳,用于确定获取哪一个时刻的最新价(maybe for ban crawler?),在查看网页源代码之后,我确定时间戳的生成代码如下,给有需要的人(我发现东方财富网的这个字段都是这么生成的):

# 获取当前的时间戳
def get_timstamp():timestamp =int(int(time.time())/30)return str(timestamp)

 

转载于:https://www.cnblogs.com/zhoudayang/p/5474053.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/423627.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

spark on yarn webUI logs不能查看

执行spark on yarn 执行&#xff1a;./bin/spark-submit --class org.apache.spark.examples.SparkPi --master yarn-cluster --executor-memory 1G --num-executors 3 ./lib/spark-examples-1.6.3-hadoop2.6.0.jar 10 命令执行成功后在yarn 资源管理界面查看不了logs 参考博…

post提交,WPF,Silverlight(加深记忆写一遍)

asp.net当<form id"form1" runat"server">默认post提交是提交到本页&#xff0c;每次提交会验证viewstate所以想提交到其它页会出错&#xff0c;如果真想提交到其它页&#xff0c;那么把其它页的viewstate标识改成和这个页一样 当去掉runat"ser…

java面试题30:牛客 下列哪项不属于jdk1.6垃圾收集器?

java面试题30&#xff1a;牛客 下列哪项不属于jdk1.6垃圾收集器&#xff1f; A:Serial收集器 B&#xff1a;parNew收集器 C:CMS收集器 D:G1收集器 1.Serial收集器 单线程收集器&#xff0c;收集时会暂停所有工作线程&#xff08;我们将这件事情称之为Stop The World&…

2019最新Python爬虫高频率面试题总结(一)

今天给大家出一个关于Python爬虫面试题的总结&#xff0c;相对于来说出现频率比较高的一些&#xff01;1. 为什么 requests 请求需要带上 header&#xff1f;原因是&#xff1a;模拟浏览器&#xff0c;欺骗服务器&#xff0c;获取和浏览器一致的内容header 的形式&#xff1a;字…

Silverlight专题(15) - 你自己的视频播放器之自定义MoveToPointSlider

前言&#xff1a; 这几天在网络上看到不少人在问如何创建一个Video Player&#xff08;Silverlight版本&#xff09; 而我在微软和这方面打了不少交道 所以计划用两篇文章解答下大家的问题 本篇文章先介绍下如何创建一个自定义的滚动条 下篇文章创建完整的一个Video Player 问题…

java面试题31:结构型模式中最体现扩展性的模式是()

java面试题31&#xff1a;结构型模式中最体现扩展性的模式是&#xff08;&#xff09; A:装饰模式 B&#xff1a;合成模式 C:桥接模式 D:适配器 蒙蔽树上蒙蔽果&#xff0c;蒙蔽树下你和我 结构型模式是描述如何将类对象结合在一起&#xff0c;形成一个更大的结构&#x…

hive 多用户访问模注意问题

首先是安装mysql 安装mysql数据库及客户端 yum install mysql-server yum install mysql servicemysqld start步骤一&#xff1a; yum -y install mysql-server步骤二&#xff1a;service mysqld start步骤三&#xff1a;mysql -u root -p  Enter password: &#xff08;默认…

10行代码实现小程序支付功能!丨实战

前面给大家讲过一个借助小程序云开发实现微信支付的&#xff0c;但是那个操作稍微有点繁琐&#xff0c;并且还会经常出现问题&#xff0c;今天就给大家讲一个简单的&#xff0c;并且借助官方支付api实现小程序支付功能。 传送门&#xff1a;借助小程序云开发实现小程序支付功能…

ASP.NET站点导航(五)

理解并扩展 ASP.NET 2.0 中的站点导航系统 http://msdn.microsoft.com/zh-cn/library/aa479338.aspx 发布日期 : 2006-3-15 | 更新日期 : 2006-3-15David Gristwood Developer & Platform Group, Microsoft 适用于&#xff1a; Microsoft ASP.NET 2.0 (Beta 2) 摘要&#…

java面试题32:Java网络程序设计中,下列正确的描述是()

java面试题32&#xff1a;Java网络程序设计中,下列正确的描述是&#xff08;&#xff09; A&#xff1a;Java网络编程API建立在Socket基础之上 B:Java网络接口只支持tcP以及其上层协议 C&#xff1a;Java网络接口只支持UDP以及其上层协议 D:Java网络接口支持IP以上的所有高…

【收藏】C# WinForm开发系列 - DataGridView 使用方法集锦 - 宁波.Net技术讨论区

1.DataGridView实现课程表 testcontrol.rar 2.DataGridView二维表头及单元格合并 DataGridView单元格合并和二维表头.rar myMultiColHeaderDgv.rar 3.DataGridView单元格显示GIF图片 gifanimationindatagrid.rar 4.自定义显示DataGridView列(行头显示行号与图标,同一单元格显示…

Java中Map, List, Set和Queue的区别和使用场景

转&#xff1a;https://blog.csdn.net/kingcat666/article/details/75579632 1. Java集合类基本概念 在编程中&#xff0c;常常需要集中存放多个数据。从传统意义上讲&#xff0c;数组是我们的一个很好的选择&#xff0c;前提是我们事先已经明确知道我们将要保存的对象的数量…

java面试题33 Math.round(11.5) 等于多少 (). Math.round(-11.5) 等于多少 ( ).

java面试题33 Math.round(11.5) 等于多少 (). Math.round(-11.5) 等于多少 ( ). A 11 ,-11 B 11 ,-12 C 12 ,-11 D 12 ,-12 蒙蔽树上蒙蔽果&#xff0c;蒙蔽树下你和我。 做Java的面试题时遇到了以下这题&#xff0c;百度了一下Math.round()的修约规则&#xff0c;有的说…

VC返回文件所在的路径

//返回文件所在的路径void GetPath(CString& Des,char* src){CString TmpStr src;int Location TmpStr.ReverseFind("");Des TmpStr.Left(Location);}转载于:https://www.cnblogs.com/enterBeijingThreetimes/archive/2008/11/26/1341615.html

Protel 介绍 protel99se正式汉化版下载 Protel DXP2004简体中文版

1. Protel介绍 protel99se正式汉化版下载 Protel DXP2004简体中文版http://www.elecfans.com/soft/22/23/2008/200807315722.html2.protel99se正式汉化版免费下载http://www.elecfans.com/zhuanti/protel99se.htmProtel se&#xff1a;Protel 99SE具有丰富的设计功能&#xff0…

java面试题34下面关于程序编译说法正确的是()

java面试题34下面关于程序编译说法正确的是&#xff08;&#xff09; A:java语言是编译型语言&#xff0c;会把java程序编译成二进制机器指令直接运行 B&#xff1a;java编译出来的目标文件与具体操作系统有关 C:java在运行时才进行翻译指令 D&#xff1a;java编译出来的目…

java面试题35 给定以下JAVA代码,这段代码运行后输出的结果是()

java面试题35 给定以下JAVA代码&#xff0c;这段代码运行后输出的结果是&#xff08;&#xff09; 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 public class Test { public static int aMethod(int i)throws Exception { try{ …

HDU-4027 Can you answer these queries? --线段树

题目链接&#xff1a; http://acm.hdu.edu.cn/showproblem.php?pid4027 题意及思路&#xff1a; 有一排战舰&#xff0c;给出每个战舰的能力值&#xff0c;存在两种操作&#xff1a;第一种是把一定范围内所有战舰能力值开根号并向下取整&#xff0c;第二种是求一定区域内所有战…

Proxy server 緩存 jsp html

如果服務器端使用Proxy server,jsp頁面會出現頁面混亂的問題.(不同用戶登陸,出現的是同一個用戶的資料),為了避免這種情況存在,可以有兩種方法解決. eg: menu 所在頁面為toppanel.jsp,鏈接就為:http://localhost:8080/q/toppanel.jsp. 這樣user登陸可能會出現manager的menu,man…

shiro学习(6):shiro连接数据库

首先我们先看一下数据库 再看看数据库的测试数据 在我们创建好的maven项目中看一下目录结构 在pom.xml引入 <dependency><groupId>com.mchange</groupId><artifactId>c3p0</artifactId><version>0.9.5.2</version></dependency&g…