使用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‘‘‘ % 1
    url += "&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‘‘‘ %start
        url += "&js=var%20ngDoXCbV&param=&sortRule=-1&sortType=0&rt=48753724"
        url_list.append(url)
        start+=1
    return url_list

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

# 此处需要设置charset,否则中文会乱码
engine =create_engine(‘mysql+mysqldb://user:[email protected]: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=0
    for url in url_list:
        request = urllib2.Request(url)
        request.add_header(‘Referer‘,‘http://data.eastmoney.com/jgdy/‘)
        # 随机从user_agent池中取user
        pos =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+=1
        for item in list_data:
            one = jigoudiaoyan()
            StartDate =item[‘StartDate‘].encode("utf8")
            if(StartDate ==""):
                StartDate = None
            else:
                StartDate = datetime.datetime.strptime(StartDate,"%Y-%m-%d").date()
            SName=item[‘SName‘].encode("utf8")
            if(SName ==""):
                SName =None
            EndDate = item["EndDate"].encode("utf8")
            if(EndDate==""):
                EndDate=None
            else:
                EndDate=datetime.datetime.strptime(EndDate,"%Y-%m-%d").date()
            Description=item[‘Description‘].encode("utf8")
            if(Description ==""):
                Description= None
            CompanyName=item[‘CompanyName‘].encode("utf8")
            if(CompanyName==""):
                CompanyName=None
            OrgName=item[‘OrgName‘].encode("utf8")
            if(OrgName ==""):
                OrgName=None
            CompanyCode=item[‘CompanyCode‘].encode("utf8")
            if(CompanyCode==""):
                CompanyCode=None
            Licostaff=item[‘Licostaff‘].encode("utf8")
            if(Licostaff ==""):
                Licostaff=None
            OrgSum = item[‘OrgSum‘].encode("utf8")
            if(OrgSum ==""):
                OrgSum=None
            ChangePercent=item[‘ChangePercent‘].encode("utf8")
            if(ChangePercent ==""):
                ChangePercent=None
            else:
                ChangePercent=float(ChangePercent)
            NoticeDate=item[‘NoticeDate‘].encode("utf8")
            if(NoticeDate==""):
                NoticeDate=None
            else:
                NoticeDate=datetime.datetime.strptime(NoticeDate,"%Y-%m-%d").date()
            Place=item[‘Place‘].encode("utf8")
            if(Place==""):
                Place=None
            SCode=item["SCode"].encode("utf8")
            if(SCode==""):
                SCode=None
            OrgCode=item[‘OrgCode‘].encode("utf8")
            if(OrgCode==""):
                OrgCode=None
            Personnel=item[‘Personnel‘].encode(‘utf8‘)
            if(Personnel==""):
                Personnel=None
            Close=item[‘Close‘].encode("utf8")
            if(Close==""):
                Close=None
            else:
                Close =float(Close)
            OrgtypeName =item[‘OrgtypeName‘].encode("utf8")
            if(OrgtypeName==""):
                OrgtypeName=None
            Orgtype=item[‘Orgtype‘].encode("utf8")
            if(Orgtype==""):
                Orgtype=None
            Maincontent=item[‘Maincontent‘].encode("utf8")
            if(Maincontent==""):
                Maincontent=None
            one.StartDate=StartDate
            one.SName=SName
            one.EndDate=EndDate
            one.Description=Description
            one.CompanyName=CompanyName
            one.OrgName=OrgName
            one.CompanyCode=CompanyCode
            one.Licostaff=Licostaff
            one.OrgSum=OrgSum
            one.ChangePercent=ChangePercent
            one.NoticeDate=NoticeDate
            one.Place=Place
            one.SCode=SCode
            one.OrgCode=OrgCode
            one.Personnel=Personnel
            one.Close=Close
            one.OrgtypeName=OrgtypeName
            one.Orgtype=Orgtype
            one.Maincontent=Maincontent
            session.add(one)
            session.commit()
        print ‘percent:‘ ,count*1.0/pages,"complete!,now ",count
        # delay 1s
        time.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‘) 
时间: 2024-10-21 11:00:44

使用python爬取东方财富网机构调研数据的相关文章

Python爬取天气网历史天气数据

我的第一篇博客,哈哈哈,记录一下我的Python进阶之路! 今天写了一个简单的爬虫. 使用python的requests 和BeautifulSoup模块,Python 2.7.12可在命令行中直接使用pip进行模块安装.爬虫的核心是利用BeautifulSoup的select语句获取需要的信息. pip install requests pip install bs4 以武汉市2017年5~7月的历史为例爬取天气网中武汉市的历史天气数据. 7月对应的网址为http://lishi.tianqi

python 爬取天猫美的评论数据

笔者最近迷上了数据挖掘和机器学习,要做数据分析首先得有数据才行.对于我等平民来说,最廉价的获取数据的方法,应该是用爬虫在网络上爬取数据了.本文记录一下笔者爬取天猫某商品的全过程,淘宝上面的店铺也是类似的做法,不赘述.主要是分析页面以及用Python实现简单方便的抓取. 笔者使用的工具如下 Python 3--极其方便的编程语言.选择3.x的版本是因为3.x对中文处理更加友好. Pandas--Python的一个附加库,用于数据整理. IE 11--分析页面请求过程(其他类似的流量监控工具亦可).

python爬取ajax动态生成的数据 以抓取淘宝评论为例子

在学习python的时候,一定会遇到网站内容是通过ajax动态请求.异步刷新生成的json数据的情况,并且通过python使用之前爬取静态网页内容的方式是不可以实现的,所以这篇文章将要讲述如果在python中爬取ajax动态生成的数据. 至于读取静态网页内容的方式,有兴趣的可以查看博客内容. 这里我们以爬取淘宝评论为例子讲解一下如何去做到的. 这里主要分为了四步: 一 获取淘宝评论时,ajax请求链接(url) 二 获取该ajax请求返回的json数据 三 使用python解析json数据 四

python爬取B站千万级数据,发现了这些热门UP主的秘密!

Python(发音:英[?pa?θ?n],美[?pa?θɑ:n]),是一种面向对象.直译式电脑编程语言,也是一种功能强大的通用型语言,已经具有近二十年的发展历史,成熟且稳定.它包含了一组完善而且容易理解的标准库,能够轻松完成很多常见的任务.它的语法非常简捷和清晰,与其它大多数程序设计语言不一样,它使用缩进来定义语句. Python支持命令式程序设计.面向对象程序设计.函数式编程.面向切面编程.泛型编程多种编程范式.与Scheme.Ruby.Perl.Tcl等动态语言一样,Python具备垃圾回收

利用python爬取贝壳网租房信息

最近准备换房子,在网站上寻找各种房源信息,看得眼花缭乱,于是想着能否将基本信息汇总起来便于查找,便用python将基本信息爬下来放到excel,这样一来就容易搜索了. 1. 利用lxml中的xpath提取信息 xpath是一门在 xml文档中查找信息的语言,xpath可用来在 xml 文档中对元素和属性进行遍历.对比正则表达式 re两者可以完成同样的工作,实现的功能也差不多,但xpath明显比re具有优势.具有如下优点:(1)可在xml中查找信息 :(2)支持html的查找:(3)通过元素和属性

python爬取安居客二手房网站数据(转)

之前没课的时候写过安居客的爬虫,但那也是小打小闹,那这次呢, 还是小打小闹 哈哈,现在开始正式进行爬虫书写 首先,需要分析一下要爬取的网站的结构: 作为一名河南的学生,那就看看郑州的二手房信息吧! 在上面这个页面中,我们可以看到一条条的房源信息,从中我们发现了什么,发现了连郑州的二手房都是这么的贵,作为即将毕业的学生狗惹不起啊惹不起 还是正文吧!!! 由上可以看到网页一条条的房源信息,点击进去后就会发现: 房源的详细信息. OK!那么我们要干嘛呢,就是把郑州这个地区的二手房房源信息都能拿到手,可

python爬取opgg的LOL英雄数据

完整源码链接: https://pan.baidu.com/s/1CWLXwlJGcq01jww8HXu3zg   (加入了部分图形界面) 由于爬取结果都是英语的版本,所以需要翻译. 另外的两个txt文件是翻译,已经完成了大部分基础的翻译,如想需要添加可以按格式填写 运行效果: 代码思路和步骤: 首先第一步,是获得所有英雄的名字和对应的url: 先观察网页的html,就能发现 <div>的data-champion-key属性中的就是英雄的名字,然后<a>的href属性就是英雄对应

Python爬取全书网小说,免费看小说

什么是网络爬虫 网络爬虫(又被称为网页蜘蛛,网络机器人,在FOAF社区中间,更经常的称为网页追逐者),是一种按照一定的规则,自动地抓取万维网信息的程序或者脚本.另外一些不常使用的名字还有蚂蚁.自动索引.模拟程序或者蠕虫. 环境:Python3.6+Windows 开发工具:你喜欢用哪个就用哪个,你开心就好! 模块: 1 import urllib.request 2 3 import re 主要思路: 1 获取主页源代码 2 获取章节超链接 3 获取章节超链接源码 4 获取小说内容 5 下载,文

python爬取科学网基金项目信息

听说学校快开学了...任务再不快点做的话,估计开学要被导师骂死,所以要查一下近年来自己研究领域的基金中标情况! 遇到的问题 导师给了个科学网的网址让我自己查基金,查完告诉他结果,可是! 在科学网查询的时候,发现只要同一IP短时间内访问 10次 左右,网页就会说你 访问太频繁 了...然后 等个10分钟左右才能重新访问 在科学网碰壁后,我先是查了下有没有别的基金查询网站,然后发现在一众网站中,还是科学网的信息更全面一点(nsfc,medsci,letpub等),然后就还是爬虫叭!!! 1. 了解科