Py学习  »  Python

手把手教你学python第五课:各种渠道获取数据,快速学会windpy和网络爬虫

与尔岩说 • 2 年前 • 446 次点击  

 快速高效学会python的终极奥义:过、抄、仿、改、调、看、练、创、悟


正文开始前,再照例念叨几句。



01



关于使用windpy获取金融数据


这里需要区分使用windpy包包和使用万矿平台获取数据的区别,万矿平台相当于是一个wind搭建好的策略框架,有它自己的取数据和回测框架,下面先介绍下万矿的用法:

1)如何找到平台?

打开wind,通过以下路径进入,或者直接在百度搜索万矿量化平台,第一个链接就是~~


2)如何使用基本功能?

进入万矿首页,点击页面右上角的研究,就进入到了万矿的研究界面,您的所有研究需求都在这里实现,下图就是点击进入的研究界面,研究界面最重要的是1和2部分: 

第2部分的文件管理区:用于管理各种类型的文件,如用于数据分析和策略研究的Notebook 文件、用于实现投资策略模拟交易的投资策略文件、还有用于存储数据的数据文件(.xlsx、.xls、.csv),还有lib库文件。 

第1部分文件操作:用于新建 Notebook 或投资策略或文件夹,或上传本地的 Notebook 文件和数据文件。 

其余区域:动手鼠标点点就会啦


notebook跟jupyter长得一模一样,参考上节课的使用就可以,代码都是写在一行行的单元中; 可通过+代码添加单元;每行单元都有2种模式:“代码”模式用来运行代码;“文本”模式用于编写文档,支持 Markdown。

3)如何进行数据提取和分析?

step1: 通过 WindPy 库的 API 函数提取金融数据, WindPy 在平台上可以傻瓜的直接点出来生成代码或是查看帮助文档 ~ 

step2: 对提取的数据进行动态可视化展示,用到WindCharts可视化库,WindCharts的详细使用请查看帮助文档 ~


4)如何进行回测?

具体的策略框架基本分为三个部分,首先需要导入策略框架,叫windAlgo,入成功后,需要定义两个函数,一个是初始化的函数,里面规定了初始的资金、回撤的标的以及回测开始的时间;其次是策略函数,这个函数是需要修改的重点,也就是把你的策略翻译成代码写进来就可以,万矿里面自带了很多策略指标库,直接使用talib提取即可;最后就是引用这两个函数,自己跑策略啦!~~


框架结构1:该种回测框架只在handle_data函数中写策略,一般适用于技术面策略、套利策略等。


框架结构2 :该种框架是通过schedule函数来编写策略,可设置多个schedule函数,该种框架一般适用于选股策略。

4)如何使用回测策略?

都是在投资策略界面中实现模拟交易功能,所以还停留在 Notebook 界面的小伙伴记得点击左侧文件管理区的投资策略,进入投资策略界面; 

方式1:可将写有策略的 Notebook 文件点击右上方按钮区的另存为,将其保存为投资策略文件,然后切换回投资策略界面进行模拟回测;

方式2:编程基础较好的小伙伴可以直接在投资策略界面的源码界面编写策略程序,然后进行后续的回测和模拟交易; 


下图是投资策略界面有关模拟回测的相关截图,详细的使用说明可参考帮助文档快速入门中的投资策略部分


那么如何使用windpy包包呢,首先是安装这个包包,这里wind很贴心,只要在我的-插件管理-修复python插件点一点,就能安装上~~


那代码怎么写呢,教你一个傻瓜但是很管用的方法,直接在wind里输入CG,就会跳出来代码生成器,然后你在wind里怎么提取数据就在这里怎么提取,点运行会直接生成代码以及取出的数据的实例,根本不用自己去记忆了~~


这里也粘贴一些常用的代码,方便爸爸们直接copy

## 包包导入from WindPy import *w.start()
##提取EDB数据,把时间、指标ID换掉就可以提取你想要的的数据,month_start = "2007-10-29"month_end="2021-03-15"w_pmi=w.edb('M0017126', month_start, month_end, "Period=M")df_pmi=pd.DataFrame(w_pmi.Data, index=w_pmi.Codes, columns=w_pmi.Times)df_pmi=pd.DataFrame(df_pmi.values.T, index=w_pmi.Times, columns=w_pmi.Codes)
##提取WSD数据,把时间、指标ID换掉就可以提取你想要的的数据month_start = "2007-10-29"month_end="2021-03-15"pft_ori=w.wsd('CBA05833.CS','close',month_start,month_end)data=pd.DataFrame([pft_ori.Times,pft_ori.Data[0]]).transpose()



02



关于在网络上直接爬取数据


1)什么是爬虫?到底是什么原理?

实际上就是爬取藏在HTML里面的数据,那首先就要理解HTML的构成和原理,这里做个简单解释~~

超文本标记语言(英语:HyperText Markup Language,简称:HTML)是一种用于创建网页的标准标记语言。HTML是一种基础技术,常与CSS、JavaScript一起被众多网站用于设计网页、网页应用程序以及移动应用程序的用户界面。网页浏览器可以读取HTML文件,并将其渲染成可视化网页。HTML描述了一个网站的结构语义随着线索的呈现,使之成为一种标记语言而非编程语言。

所以事实上HTML就是一种包含了文本、图片之类各种东西的一个类似于word文档一样的东西,那它用什么打开呢,用浏览器打开; 爬虫的基本原理和网页的基本规范参见视频哈~~因为之前写了一大堆。。不小心忘记保存,然后终于可以发了,结果发现根本没办法保存,垃圾wx了,写个爬虫链接都不能放,太垃圾了。。。大家自行参考下视频吧,我尝试用最简单易懂的方式来把它讲清楚~~


HTML Basics

  • 超文本标记语言(HyperText Markup Language)

  • 用于写网页的一种语言

  • HTML 标签(tags)

    • 尖括号<>

    • 通常成对出现

一些常见的标签

  • heading

    • ...
  • paragraph

  • line break


  • link with attribute

  • More details about tags can be found here:



    2)如何利用浏览器inspect功能?

    用谷歌浏览器打开任意一个网站,找一个空白的位置右键-查看网页源代码,这时就会打开一个新的页面这个页面就是这个网站的HTML源代码了,我们可以通过这个页面来看我们要的信息在哪里,但是感觉非常不方便,因为有太多无用的信息做干扰,我们无法快速掌控网页的结构。所以我们可以用另一种方式查看源代码。

    比较推荐的是,找一个空白的位置右键-检查,就会弹出一个框,如下图所示

    (如果没有看到这个界面,注意要切换到Element中)

    这个页面最大的好处是通过折叠来让人更快探索出网页的结构。

    其中的那些代码就是HTML代码,该页面的一个个标题就存在这一个个li里面。点击li前面的三角就可以展开具体的代码内容,如下图所示

    可以看到文章的标题(打造一个高性能、易落地的公链开发平台)就在这个源代码之中,也就是说在我们刚刚获得的r.text字符串之中。而我们代码定位路径也一目了然了,因为每个li里面都会有一个

    而每一个div里面都会有一个h2 里面有一个a,a中包含我们要的标题名称。所以我们就用find_all找到所有这样的div标签,存储为一个list,再对list进行循环,对每一个元素提取h2 a 再提取标签中的内容。

    当然我们也可以find_all最外面的li标签,再一层层往里找,都是一样的。只要找到定位信息的唯一标识(标签或者属性)就可以了。

    虽然在这里看源代码可以折叠一些没用的代码,但是其实还有一些更好用的工具来辅助我们找到我们要的信息在网页源码中的位置。比如下面这个鼠标符号。

    在所有代码都折叠起来的情况下,点击这个鼠标,之后再去点击网页中的元素,浏览器就会自动帮你把你点击的元素选中出来,其实你鼠标悬在一个元素上面的时候,就已经帮你定位了,如下图所示


    3)有哪些包包用来写爬虫?

    Requests

    Requests: 7个主要方法

    • requests.request():构造一个请求,支撑以下各方法的基础方法

    • requests.get():获取HTML网页的主要方法,对应于HTTP的GET

    • requests.head():获取HTML网页头信息的方法,对应于HTTP的HEAD

    • requests.post():向HTML网页提交POST请求的方法,对应于HTTP的POST

    • requests.put():向HTML网页提交PUT请求的方法,对应于HTTP的PUT

    • requests.patch():向HTML网页提交局部修改请求,对应于HTTP的PATCH

    • requests.delete():向HTML页面提交删除请求,对应于HTTP的DELETE

    Requests的get()方法

    • r = requests.get(url)

      • r -> 返回一个包含服务器资源的Response对象,即爬虫返回的内容

      • get()方法构造一个向服务器请求资源的Request对象

    • requests.get(url, params=None, **kwargs)

      • url: 拟获取页面的url地址

      • params: url中的额外参数

      • **kwargs: 控制访问的参数

    import requestsr = requests.get("http://www.douban.com",timeout=0.001) # 超时参数print(r.status_code)print(type(r))

    Response对象的常用属性

    • r.status_code: HTTP请求的返回状态(200:成功,其他代码:失败)

    • r.text: 返回的url页面内容

    • r.encoding: 从HTTP header中推测的字符编码方式

    • r.apparent_encoding: 从文本内容中分析出的备选字符编码方式

    ## Demo: Response对象的属性和字符编码处理import requestsr = requests.get("http://www.sjtu.edu.cn")print(r.status_code)print(r.encoding)print(r.apparent_encoding)print(r.text)
    
    
        
    # r.encoding = r.apparent_encoding# print(r.text)


    实例:抓取京东商品页面

    使用Requests库抓取此链接中的商品页面:

    "https://item.jd.com/497227.html"

    import requestsurl = "https://item.jd.com/497227.html" #空气净化器r = requests.get(url, timeout=30)r.raise_for_status() # throw HTTPError if the status code is not 200r.encoding = r.apparent_encoding # handling encoding issueprint(r.text[:1000])


    实例: 抓取亚马逊中国商品页面

    • 使用Requests库抓取此链接中的商品页面:

    • "https://www.amazon.cn/dp/B005GNM3SS/"

    import requestsurl = "https://www.amazon.cn/dp/B005GNM3SS/" #空气净化器# url = "https://www.amazon.cn/gp/product/B01ARKEV1G" # 机器学习西瓜书r = requests.get(url, timeout=30)print(r.status_code)r.encoding = r.apparent_encoding # handling encoding issueprint(r.text)print(r.request.headers)
    ## Demo: set user-agnet using "headers"import requestsurl = "https://www.amazon.cn/dp/B005GNM3SS/" #空气净化器headers = {'User-Agent':'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36'}# headers = {'User-Agent':'Mozilla/5.0'}r = requests.get(url, timeout=30, headers=headers) # add header information for user-agentprint(r.status_code)r.encoding = r.apparent_encoding # handling encoding issueprint(r.text)


    实例: 百度搜索关键词提交

    • 百度的关键词接口:"http://www.baidu.com/s?wd=keyword"

    ## Demo: set keywords to submit using "params"import requests
    keywords={'wd':'python scrape'}r = requests.get("http://www.baidu.com/s",params=keywords)print(r.status_code)print(r.request.url)print(r.text)


    Requests抓取网页的通用代码

    ## Requests抓取网页的通用代码: 加入异常捕获,超时设定,编码设定,浏览器伪装import requests
    # define get_html() functiondef get_html(url): try: r = requests.get(url, headers={'User-Agent':'Mozilla/5.0'}, timeout=30) r.raise_for_status() # throw HTTPError if the status code is not 200 r.encoding = r.apparent_encoding # handling encoding issue return r.text except: return "Error: something is Wrong!"
    # call get_html() functionurl_bad = "www.baidu.com"print(get_html(url_bad))print()url = "http://www.baidu.com"print(get_html(url))


    BeautifulSoup

    Parsing Webpages

    • BeautifulSoup: a powerful library for parsing webpages

      • 还有一些其他的类库,如lxml(事实上,BeautifulSoup支持使用lxml解析器)

    • 另外,我们可以经常使用浏览器来帮助我们理解HTML页面的结构

      • 'Ctrl-Shift I' in Chrome, or 右击 -> view page source


    • Installation:

      • pip install beautifulsoup4 (如果出现权限错误,可以尝试以管理员身份运行anaconda prompt)

      • pip install lxml



    htmlString = "<html><head><title>This is a titletitle>head><body><h2>Testh2><p>Hello world!p>body>html>"
    from bs4 import BeautifulSoupsoup = BeautifulSoup(htmlString,"html.parser")print(htmlString)print()print(soup.prettify()) # 友好的输出:prettify()方法


    from bs4 import BeautifulSoupimport requests
    url = "http://www.crummy.com/software/BeautifulSoup"r = requests.get(url)
    ## get BeautifulSoup objectsoup = BeautifulSoup(r.text,"html.parser")print(type(soup))## get attribute value from an element:## find tag: this only returns the first occurrence, not all tags in the stringfirst_tag = soup.find('a')print(first_tag)
    ## get attribute `href`print(first_tag.get('href'))print(first_tag['href'])
    ## get textprint(first_tag.string)print(first_tag.text)print(first_tag.get_text())



    03

    可以直接copy的代码,都封装好了,可以直接用~~


    import requests
    import ast
    import json

    import sys
    reload(sys)
    sys.setdefaultencoding('utf-8')

    headers = {
    'User-Agent': 'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:39.0) Gecko/20100101 Firefox/44.0',
    'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
    'Accept-Language': 'en-US,en;q=0.5',
    'Accept-Encoding': 'gzip, deflate',
    'Connection': 'keep-alive'}

    当网页可以找到相应的json数据的时候:

    url = ""
    # 在网页header页面拉到最下面然后找到postdata部分
    postdata= {
    }
    import requests
    # 请求
    def get_html(url):
    try:
    r = requests.get(url, headers={'User-Agent':'Mozilla/5.0'}, timeout=30)
    r.raise_for_status() # throw HTTPError if the status code is not 200
    r.encoding = r.apparent_encoding # handling encoding issue
    return r.text
    except:
    return "Error: something is Wrong!"
    result = requests.post(url,data=postdata, headers=headers).text

    # 对返回的string进行按照 自己的 需求进行清洗
    result = result.replace('\n','')[4:]
    result = result.replace('null,', '')

    # 将list dic 类型的string转成 list dic
    clean_result = ast.literal_eval(result)

    print json.dumps(clean_result).decode("unicode-escape")

    当需要用到解析网页的时候:

    一般来说会用到Beautiful Soup: https://www.crummy.com/software/BeautifulSoup/bs4/doc.zh/
    BeautifulSoup库是用来解析、遍历、维护“标签树”的功能库(t.name,t.string,t.attrs)
    另一种方法是RE: https://docs.python.org/3/library/re.html

    def getMobileInfo(base_url, page):
    result = []

    for i in range(0,page,1):
    # 拼接url
    url = ''.join([base_url, str(i), '.html'])
    html = requests.get(url, headers=headers ).text
    beautyHtml = BeautifulSoup(html, 'lxml')#解析式的一种,错误最少,最全的
    #一般来说都会寻找相应的
    div_list = beautyHtml.find_all('div', attrs={
    'class': 'feeds-item'})

    if div_list:
    for item in div_list:
    # 取得tag属性的值
    href = item.div.h3.a['href']
    # 取得tag的值
    name = item.div.h3.a.text.encode('utf-8')
    reg = '201\d年\d+月'
    regResul = re.findall(reg, name, re.S)
    if len(regResul) != 0:
    print '___Name:', name
    print '___ADD', href
    result.append(href)
    return result
    ## get all links in the page
    link_list = [link.get('href') for link in soup.find_all('a')]
    for link in link_list:
    if link is not None and link[:4] == 'http': # Note: lazy evaluation
    external_links.append(link)
    [link for link in link_list if l is not None and l.startswith('http')]

    网页的结构和re相关文档

    各种tag等的含义:https://www.w3schools.com/tags/
    大部分的浏览器会将HTML解析成DOM:https://www.w3.org/DOM/
    正则表达式:https://regexone.com/ ,https://docs.python.org/3/howto/regex.html
    正则表达式测试:http://regexr.com/
    代理池使用:/wenshu_scrach/将文件夹和smilerequest.py引入即可(先cd到ip文件夹然后run起来)

    定制好的函数

    list抓取

    def getListData(outputfile, *args):
    url = ''.join(args)
    print url
    html = requests.get(url, headers=headers).text
    beautyHtml = BeautifulSoup(html, 'lxml')

    # 第三步:最重要的定制规则
    # 搜索tag
    tag = beautyHtml.find('div', attrs={'class': 'bottom'})
    tags = beautyHtml.find_all('div')
    tags = beautyHtml.find_all(id='html')
    sub_tags = tag.find_all('div')

    # 获取tag的值
    tag_value = tag.div.string # type: bs4.element.NavigableString 也是一种unicode, 可以用str() 进行转换
    tag_value = tag.head.text # type: bs4.element.NavigableString 也是一种unicode, 可以用str() 进行转换

    # 获取property的值
    property_value = tag['class'].string


    if __name__ == '__main':
    # 第一步:确定好输出文件
    inputfliePath = '/Users/i309929/Desktop/input.txt'
    outputfile = open(inputfliePath, 'w')

    # 第二步:定制url
    url = 'http://www.aqistudy.cn/historydata/index.php'
    getListData(outputfile, url)

    outputfile.close()

    表格抓取

    def getExcelFromWebTable(outputSheet, *keyword):
    url = ''.join(keyword)
    print url
    html = requests. get(url, headers=headers).text
    beautyHtml = BeautifulSoup(html, 'lxml')

    tables = beautyHtml.find_all('table')
    if tables:
    print "一共找到 " + str(len(tables)) + " 表格"
    print "默认选取第一个表格......."
    first_table = tables[0]
    trs = first_table.find_all('tr')

    if trs:
    row_count = len(trs)
    # print "行数:" + str(row_count)
    for i in xrange(0, row_count):
    global start_row
    tr = trs[i]
    tds = tr.find_all('td')
    if tds==None:
    tds = tr.find_all('th')
    col_count = len(tds)
    # print "列数" + str(col_count)
    for j in xrange(0, col_count):
    td = tds[j]
    text = td.text
    outputSheet.write(start_row, j + 1, label=text)
    start_row = start_row + 1
    else:
    print "表格tr中没有数据"
    else :
    print url + " 中没有表格格式数据"

    if __name__ == '__main__':
    '''
    ------------------------------------------------------------------------------------------------
    从text文件中中每一行读取关键字变量进行遍历
    '''

    # inputFilePath = '/Users/i309929/Desktop/cities.txt'
    # queryKeywords = open(inputFilePath, 'r')
    #
    # outputFile = ExcelWrite.Workbook(encoding='utf-8')
    # outputSheet = outputFile.add_sheet("output_sheet", cell_overwrite_ok=True)
    #
    # for keyword in queryKeywords:
    # global start_row
    # start_row = start_row + 1
    # outputSheet.write(start_row, 0, label=keyword)
    # keyword = string.rstrip(keyword)
    # print '-------------keyword: ' + str(keyword) + ' ----: '
    # baseURL = 'http://www.aqistudy.cn/historydata/monthdata.php?city='
    # getExcelFromWebTable(outputSheet, baseURL, str(keyword))
    # sleep(1)
    #
    # queryKeywords.close()
    # outputFile.save('/Users/i309929/Desktop/output.xls')

    '''
    ------------------------------------------------------------------------------------------------
    直接进行遍历
    '''

    outputFile = ExcelWrite.Workbook(encoding='utf-8')
    outputSheet = outputFile.add_sheet("output_sheet", cell_overwrite_ok=True)

    getExcelFromWebTable(outputSheet, 'http://tianqihoubao.com/weather/top/beijing.html')

    outputFile.save('/Users/i309929/Desktop/output.xls')


    Python社区是高质量的Python/Django开发社区
    本文地址:http://www.python88.com/topic/115774
     
    446 次点击