A Song of Python and Anaconda


  • Startseite

  • Archiv

  • Tags

测试Daocloud

Veröffentlicht am 2016-10-20

测试Daocloud

1、话说现在新浪SAE每天开始收10个豆,加上他主推SVN管理,且不支持同时SVN+Git的管理方法。
这使得带来一定的不方便,所以决定找一个代替SAE的。正好看到别人的帖子,所以决定测试下Daocloud

2、案例:

http://vansnowpea-van-2048.daoapp.io/

3、代码,转自:https://my.oschina.net/u/923087/blog/286050:

# -*- coding: utf-8 -*-
"""
Created on Tue Jul  1 14:15:39 2014

@author: kelvin
"""

import random

class game2048:
    totalScore = 0
    v = [[2, 8, 8, 2],
         [4, 2, 4, 8],
         [2, 4, 2, 0],
         [4, 2, 4, 0]]
    '''
    v = [[0, 0, 0, 0],
         [0, 0, 0, 0],
         [0, 0, 0, 0],
         [0, 0, 0, 0]]
    '''
    def __init__(self):
        for i in range(4):
            self.v[i] = [random.choice([0,0,0,2,2,4]) for x in range(4)]


    def display(self):
        print('{0:4} {1:4} {2:4} {3:4}'.format(self.v[0][0], self.v[0][1], self.v[0][2], self.v[0][3]))
        print('{0:4} {1:4} {2:4} {3:4}'.format(self.v[1][0], self.v[1][1], self.v[1][2], self.v[1][3]))
        print('{0:4} {1:4} {2:4} {3:4}'.format(self.v[2][0], self.v[2][1], self.v[2][2], self.v[2][3]))
        print('{0:4} {1:4} {2:4} {3:4}'.format(self.v[3][0], self.v[3][1], self.v[3][2], self.v[3][3]))
        print('得分为:{0:4}'.format(self.totalScore))
        print('游戏是否结束:{0:4}'.format(self.isOver()))
    #重新排列
    def align(self,vList, direction):
        for i in range(vList.count(0)):
            vList.remove(0)
        zeros = [0 for x in range(4-len(vList))]
        if direction == 'left':
            vList.extend(zeros)
        else:
            vList[:0] = zeros
    #将相同的元素相加,返回新增积分
    def addSame(self,vList, direction):
        increment=0
        if direction == 'left':
            for i in [0,1,2]:
                if vList[i]==vList[i+1] and vList[i+1]!=0:
                    vList[i] *= 2
                    vList[i+1] = 0
                    increment += vList[i]
        else:
            for i in [3,2,1]:
                if vList[i]==vList[i-1] and vList[i-1]!=0:
                    vList[i] *= 2
                    vList[i-1] = 0
                    increment += vList[i]
        return increment
    #处理行和方向,返回新增积分
    def handle(self, vList, direction):
        self.align(vList, direction)
        increment = self.addSame(vList, direction)
        self.align(vList, direction)
        self.totalScore += increment #直接加到总值
        return increment
    #判断游戏是否结束
    def judge(self):

        if self.isOver():
            print('你输了,游戏结束!')
            return False
        else:
            if self.totalScore >= 2048:
                print('你赢了,游戏结束!但是你还可以继续玩。')
            return True
    #判断游戏是否真正结束
    def isOver(self):
        N = self.calcCharNumber(0)
        if N!=0:
            return False
        else:
            for row in range(4):
                flag = self.isListOver(self.v[row])
                if flag==False:
                    return False    
            for col in range(4):
                # 将矩阵中一列复制到一个列表中然后处理
                vList = [self.v[row][col] for row in range(4)]
                flag = self.isListOver(vList)
                if flag==False:
                    return False
        return True

    #判断一个列表是否还可以合并
    def isListOver(self, vList):
        for i in [0,1,2]:
            if vList[i]==vList[i+1] and vList[i+1]!=0:
                return False
        return True
    def calcCharNumber(self, char):
        n = 0
        for q in self.v:
            n += q.count(char)
        return n
    def addElement(self):
        # 统计空白区域数目 N
        N = self.calcCharNumber(0)
        if N!=0:
            # 按2和4出现的几率为3/1来产生随机数2和4
            num = random.choice([2, 2, 2, 4]) 
            # 产生随机数k,上一步产生的2或4将被填到第k个空白区域
            k = random.randrange(1, N+1)    #k的范围为[1,N]
            n = 0
            for i in range(4):
                for j in range(4):
                    if self.v[i][j] == 0:
                        n += 1
                        if n == k:
                            self.v[i][j] = num
                            return


    def moveLeft(self):
        self.moveHorizontal('left')
    def moveRight(self):
        self.moveHorizontal('right')
    def moveHorizontal(self, direction):
        for row in range(4):
            self.handle(self.v[row], direction)

    def moveUp(self):
        self.moveVertical('left')
    def moveDown(self):
        self.moveVertical('right')
    def moveVertical(self, direction):
        for col in range(4):
            # 将矩阵中一列复制到一个列表中然后处理
            vList = [self.v[row][col] for row in range(4)]
            self.handle(vList, direction)
            # 从处理后的列表中的数字覆盖原来矩阵中的值
            for row in range(4):
                self.v[row][col] = vList[row]

    #主要的处理函数
    def operation(self):
        op = input('operator:')
        if op in ['a', 'A']:    # 向左移动
            self.moveLeft()
            self.addElement()
        elif op in ['d', 'D']:  # 向右移动
            self.moveRight()
            self.addElement()
        elif op in ['w', 'W']:  # 向上移动
            self.moveUp()
            self.addElement()
        elif op in ['s', 'S']:  # 向下移动
            self.moveDown()
            self.addElement()
        else:
            print('错误的输入。请输入 [W, S, A, D] 或者是其小写')    

#开始
print('输入:W(上移) S(下移) A(左移) D(右移), press <CR>.')
g =game2048()
flag = True
while True:
    g.display()
    flag = g.judge()
    g.operation()
    flag = g.judge()

从零开始 Python 微信公众号开发【转帖】

Veröffentlicht am 2016-10-20

从零开始 Python 微信公众号开发【转帖】

1、虽然在8月底的时候我也有总结一篇基于SAE的订阅号的实现的日志。不过也就是简单实现而已。

2、今天偶然看到小段的总结文档,写的比较详细,忍不住转发下,以下是原文地址:

https://zhuanlan.zhihu.com/p/21354943

3、要强调下,如果使用SAE新浪云,是需要实名认证的。

4、最近也从github或搜索发现了一些不错的微信的sdk,包括但不限于:

  • https://github.com/littlecodersh/ItChat
  • http://wechat-python-sdk.com/

5、然后今天发生了喜感的一幕,当和little聊起之前曾给他发过email请教过细节等,他回复说,当时正好有人写了email,才想起做一个这样的sdk。

数据分析和一个工具OpenRefine【Python】

Veröffentlicht am 2016-10-17

数据分析和一个工具OpenRefine

1、在阅读《Python网络数据采集》第七章的时候看到的案例,记录细节分析。

2、来简单体会下他的作用,根据书上的例子,我选定了之前程序得到的csv文件,导入后,的界面如下图:

可以看到Programming language,的栏目,这里要从77行中,筛选出同时有3种语言技能的,先在上面的下拉三角点开,使用text filter,然后配合RE表达式: .+,.+,.+ 输入到左侧,即可:

3、此软件关于正则表达式的使用,可参考此网址:

https://github.com/OpenRefine/OpenRefine/wiki/General-Refine-Expression-Language

维基百科某网页表格的csv保存的分析【Python】

Veröffentlicht am 2016-10-15

维基百科某网页表格的csv保存的分析

1、在阅读《Python网络数据采集》第五章的时候看到的案例,记录细节分析。

目标网址:
http://en.wikipedia.org/wiki/Comparison_of_text_editors

中的一个表格,

这是结果图:

2、代码:

import csv
from urllib.request import urlopen
from bs4 import BeautifulSoup

html = urlopen("http://en.wikipedia.org/wiki/Comparison_of_text_editors")
bsObj = BeautifulSoup(html, "html.parser")
#The main comparison table is currently the first table on the page
table = bsObj.findAll("table",{"class":"wikitable"})[0]
# print(table)
rows = table.findAll("tr")
# print(rows)

csvFile = open("c:\\van\\editors.csv", 'wt', newline='', encoding='utf-8')
writer = csv.writer(csvFile)
try:
    for row in rows:
        csvRow = []
        for cell in row.findAll(['td', 'th']):
            csvRow.append(cell.get_text())
        writer.writerow(csvRow)
finally:
    csvFile.close()

3、上述代码的主要目的,是把对应url的表格的文字信息,提取出来,保存到csv。那么他是怎么一步步做到的?

首先,我们来打开url看下网站的目标内容,如下图是一个色彩鲜艳的表格:

其次,我们查看下网页源代码,格式清晰的很,并且代码很长一共7910行的html,可这只是维基百科的一页而已!并且从这么多的html代码中快速的提取出我们需要的数据信息,应该怎么做呢?

一般来说,提取数据有2个比较通用的方法,
第一、无视他的源代码,我就查看目标内容的路径,可通过浏览器自带的copy xpath配合lxml提取,或者如果你习惯bs4的话,用类似方法。

第二,根据F12找到目标区域,比如一个表格的所在大的路径,然后由大往小的逐步提取。显然本文使用的是这个方法。当鼠标移动到

<table class="wikitable sortable jquery-tablesorter" style="text-align: center; font-size: 85%; width: auto; table-layout: fixed;">

这一行代码的时候,整个目标表格的颜色就变了。如下图,

4、现在重点分析下这行代码:

table = bsObj.findAll(“table”,{“class”:”wikitable”})[0]

根据第三条中的分析,已经知道把对应表格中所有含有wikitable的class找出来,那么为什么要这么写?
此时,对照下本例python代码中,按照class搜索{“class”:”wikitable”},实际上得到的是搜索class=”wikitable sortable”,如下的html代码(其中一条):

<table class="wikitable sortable" style="text-align: center; font-size: 85%; width: auto; table-layout: fixed;">

也就是说,bs4的findall是找到了类名带有”wikitable”,就自动把”wikitable sortable”也找出来,但对照lxml的xpath来说,如果class=”wikitable”,则搜索结果为空,要写完整的class=“wikitable sortable“,另外要注意这里有一个大坑,因为F12下的class是”wikitable sortable jquery-tablesorter”,和源代码是不对应的,这会导致python里用xpath找不到内容!

那么为何要在代码的后面加上[0] ? 如果只用下面的代码:

bsObj.findAll("table",{"class":"wikitable"})

就本例使用bs4分析来说, 其实得到的是bs4.element.ResultSet ,从字面翻译,可理解成bs4的结果集,不过应该是一个列表, 而要提取里面的内容,就加上[0],此时从bs4的角度来说,得到了一个bs4.element.Tag , 从列表的内容提取来说,得到了列表里第一个元素的内容。

5、接下来分析这一句:

rows = table.findAll("tr")

这一行是得到表格中所有按行的内容,这包含了表格头的黑色字体。如下图: (顺便请翻到此贴底部的参考资料,学习下tr,th,td的区别。

6、接下来,当开始写入csv的时候,是按行写的,包含了表格头的内容,看下代码:

try:
        for row in rows:
            csvRow = []
            for cell in row.findAll(['td', 'th']):
                csvRow.append(cell.get_text())
            writer.writerow(csvRow)

其中 ‘th’ 是表格头,‘td’是表格内容。

7、相对与上述第二种提取方法,这里详细说下第一种提取方法:

检测表格中黑体的表格头(以name为例)和表格内容(以’acme’为例):

//*[@id=”mw-content-text”]/table[2]/thead/tr/th[1]

//*[@id=”mw-content-text”]/table[2]/tbody/tr[1]/th/a

分别得到他们的xpath地址,但格式并不统一,出现了thead和tbody。

不过好在表格内容的xpath都是有规律的,
千万要注意的是:用xpath提取表格的内容要千万小心,这是因为按照上述路径,测试结果,得到的text()返回值为空,

所以要修正下xpath路径,lxml的解析和网页源代码是有出入的,尤其遇到tboday和thead的时候,经过测试,在很多时候,python要把/thead和/tbody才能显示出内容,但这不是绝对的,因为我也遇到保留tbody才能提取成功的案例。

但还有额外的问题,因为这个表格同时有表头和表内容,而这个案例需要同时提取。而表格还有一个captain = “List of text editors”(表格的标题),也就是说,如果我们要通过直接全部提取整个表格的内容,会多出来captain的内容.

而如果把表头和表内容分开提取的话,他们的xpath在去掉/thead和/tbody之后的形式是这样的: 这里由于情况复杂,我先分析表头部分:

A)表头:

string(//*[@id="mw-content-text"]/table[2]/tr)

为何要这么写,而不用直接的text()模式呢?我们来看下

//*[@id="mw-content-text"]/table[2]/tr//text()

如果这么写,得到的结果是带有空格的,如图:

可以发现,不仅多出了空格,在Cost(US$)的栏目,还分了3行,而我们需要连续的,
综上,我们只有通过string功能来实现把空格去掉,同时把Cost(US$)合并在一起,得到的结果将是这样的:

Name
Creator
First public release
Latest stable version
Programming language
Cost (US$)
Software license
Open source

貌似thead部分的提取还比较顺利,可接下来tbody部分呢?

B)表内容:
我们先看开头的2行对应的xapth地址:

# tbody
# Acme xpath:  //*[@id="mw-content-text"]/table[2]/tbody/tr[1]/th/a
# AkelPad xpath: //*[@id="mw-content-text"]/table[2]/tbody/tr[2]/th/a

如果去掉/tbody后, 又要把表格内容全部提取,又要去掉tbody,发现只能这么写:

string(//*[@id="mw-content-text"]/table[2])

可这样是不行的,因为他不仅把表头的内容也算进去了,还把标题captain的内容也一起搞进去了。

此时,又根据表内容的序号格式,尝试这么写:

string(//*[@id="mw-content-text"]/table[2]//th/a)

期望的是,得到统一的表内容,可实际返回的却是:

Programming language

这又是什么鬼呢?
原来,代码识别的是满足上述格式条件的第一个/a 路径下的文字,而在表头里,从Programming language开始,他有a属性。

此时,又发现,既然string返回的是第一个满足条件的,那么刚修正过的表头的string表达式,其实也适合表内容的表达式啊。看来,我们只好先再提高一个层级,用:

string(//*[@id="mw-content-text"]/table[2])

貌似进入了xpath分析的死循环,做下数据清理应该也是一个路子。

8、上面分析了一大堆,结果不满意,那么lxml的有没有类似bs4的findall功能呢?

∙ iterfind() iterates over all Elements that match the path expression
∙ findall() returns a list of matching Elements
∙ find() efficiently returns only the first match
∙ findtext() returns the .text content of the first match

不过当用:

table = selector.findall('.//*[@id="mw-content-text"]/table[2]/tr')

得到的结果显示的都是element的list,不显示里面的文字,提取的命令貌似在官网上也没找到,并且尝试:print(each.text) 完全空结果,这就有点坑了。

9、从第8点的分析来看,使用bs4在提取表格的时候,优势还是较大的,因为其返回的是列表形式的html内容,使得具体的提取方便,而lxml的返回的是一个看不到内容的,并且官网上的案例似乎也不太明了。以下是尝试的lxml提取脚本:

import requests
from lxml import etree    

html = urlopen("http://en.wikipedia.org/wiki/Comparison_of_text_editors")Comparison_of_text_editors")
selector = etree.HTML(html)
#The main comparison table is currently the first table on the page
table = selector.findall('.//*[@id="mw-content-text"]/table[2]/tr')
content = []
for i in range(len(table)):
    text = selector.xpath('string(//*[@id="mw-content-text"]/table[2]/tr[%d + 1])'%i)
    print(text)
    print(len(text))
    content.append(text)
print(content)

虽然通过lxml.etree 的findall 以及 xpath配合得到了表格里的需要的文字,但是,这样的格式,要再插入csv却非常的麻烦,这是因为我们要按行插入,而返回的列表如下面的格式(下面显示的是列表第一项):

['\nName\nCreator\nFirst public release\nLatest stable version\nProgramming language\nCost (US$)\nSoftware license\nOpen source\n', 

如果打印出来则是一行行的文字形式,则形如:

Name
Creator
First public release
Latest stable version
Programming language
Cost (US$)
Software license
Open source


Acme
Rob Pike
1993
Plan 9 and Inferno
C
Free
LPL (OSI approved)
Yes

要想得到bs4的那种csv的表格形式 ,还需要额外增加很多的数据清洗代码,看上去简单,实际很复杂,比如当你想通过len()的时候计算第一项有几个单词,按我们需求是从Name到Open source 的8个单词对应csv的8个列,但python是按照字符串去统计的,返回的每个列表元素的长度肯定不同的。而如果想把\n都替换掉,则前后所需单词后紧挨在一起了。总之最后反而得不偿失,尤其是如果希望使用wt的csv写入格式的话。希望以后能找到更好的办法来解决lxml这样的表格提取问题。

In [4]: a
Out[4]: '\nName\nCreator\nFirst public release\nLatest stable version\nProgramming language\nCost (US$)\nSoftware license\nOpen source\n'

In [5]: a.replace('\n', '')
Out[5]: 'NameCreatorFirst public releaseLatest stable versionProgramming languageCost (US$)Software licenseOpen source'

In [6]: length = len(a)

In [7]: length
Out[7]: 118

10、参考:

http://jingyan.baidu.com/article/636f38bb1eb1aad6b8461088.html

西部世界 1080P高清下载和自动提醒后续新出的【Python】

Veröffentlicht am 2016-10-13

西部世界 1080P高清下载和自动提醒后续新出的

1、主要思路是,通过高清源头的网站提供的资源,爬取后,通过迅雷实现自动下载,
然后后续新出的,比如下周1更新后,脚本会自动捕捉后发邮件通知,并自动下载。

2、代码:

# -*- coding: utf-8 -*-
# python 3.5.2
# 测试系统,Win10
# Author:Van
# 实现《西部世界》有更新后自动下载,以及邮件通知
# V1.01
# 修改@href提取方法,因源头网站变更
# 请把对应的帐号密码修改成自己的


# from selenium import webdriver
import requests
from lxml import etree
import time
import os
from win32com.client import Dispatch
import smtplib
from email.mime.text import MIMEText
from email.header import Header
import copy

# hints
print('请确保电脑安装了迅雷')
print('如果你用的是破解版的迅雷,请先开启再运行程序')
print()
# requests
url = 'http://www.btbtdy.com/btdy/dy7280.html'
html = requests.get(url).content.decode('utf-8')

# lxml
selector = etree.HTML(html)
real_link = []

# to be easy, try 'starts-with' , very useful in this case :)
HDTV = selector.xpath('//a[starts-with(@title, "HDTV-1080P")]/text()')
for each in HDTV:
    print(each)


# the site modified the magnet link position with adding the span
# we should use: following-sibling function to catch it :)
href = selector.xpath('//a[starts-with(@title, "HDTV-1080P")]/following-sibling::span/a/@href')
print()
print('目前有 %d 集西部世界' %len(href))
print()

for each in href:
    # split to get the right magnet link
    each = 'magnet' + each.split('magnet')[-1]
    # print(each)
    real_link.append(each)

print('他们的磁链接是 :\n', real_link)
# define a temp_link in deepcopy to compare for new series
temp_link = copy.deepcopy(real_link)
print('temp_link is :', temp_link)




def addTasktoXunlei(down_url,course_infos):
    flag = False
    o = Dispatch("ThunderAgent.Agent.1")
    if down_url:
        course_path = os.getcwd()
        try:
            #AddTask("下载地址", "另存文件名", "保存目录","任务注释","引用地址","开始模式", "只从原始地址下载","从原始地址下载线程数")
            o.AddTask(down_url, '', course_path, "", "", -1, 0, 5)
            o.CommitTasks()
            flag = True
        except Exception:

            print(Exception.message)
            print(" AddTask is fail!")
    return flag

def new_href():
    # to judge if there is a new series of WestWorld
    time.sleep(2)
    if len(real_link) > len(temp_link):
        print('西部世界1080P有更新!')
        print('现在一共有 %d 集了。' %len(real_link))
        return True
    else:
        return False

def send_email(htm):
    # send email to notice new WestWorld is coming
    sender = 'xxxxxxxx@163.com'
    receiver = 'xxxxxxxx@qq.com,xxxxxxxx@163.com'
    subject = '西部世界 1080P有更新!'
    smtpserver = 'smtp.163.com'
    username = 'xxxxxxxx@163.com'
    password = 'xxxxxxxx'
    msg = MIMEText(htm, 'html', 'utf-8')
    msg['Subject'] = Header(subject, 'UTF-8')
    msg['From'] = sender
    msg['To'] = ','.join(receiver)
    smtp = smtplib.SMTP()
    smtp.connect(smtpserver)
    smtp.login(username, password)
    smtp.sendmail(sender, receiver, msg.as_string())
    smtp.quit()

def new_download():
    # only download the new WestWorld series
    if len(real_link) > len(temp_link):
        # 2个地址数据的差集
        new_link = list(set(real_link).difference(set(temp_link)))
        for i in new_link:
            addTasktoXunlei(i, course_infos=None)



if __name__ == '__main__':
    # download the exiting series of WestWorld
    # send_email('最新更新磁链接:'+ str(real_link))
    for i in real_link:
        addTasktoXunlei(i, course_infos=None)

    # to get the later WestWorld for each hour
    while 1:
        if new_href():
            send_email('所有的下载地址(磁链接):'+ str(real_link))
            new_download()
            time.sleep(15)
            # wait for an hour
            temp_link = real_link
            print(temp_link)
            print('神剧很好看吧,亲,耐心等下一集!~!')

3、代码分析,其中用到了deepcopy,这个功能很有用,并配合了2个数组的差集,使得可以规避定时器,而让脚本直接比较temp_link的内容,而扑捉到网站有新的更新了。另外,在地址识别的时候,一开始用.xpath 没显示内容,有点奇怪,后来根据特性,使用了strats_with识别了内容。另外,原始的邮件发送函数,是一个接收人,如果要多发,则receiver的格式为list,并修改 msg[‘To’] = ‘,’.join(receiver)

4、邮件的作用是可以利用微信绑定来推送,相对短信,更觉方便。

5、感谢:
@陌 提供了163发送email的代码
@何方 提供了高清网站源
@其他人,交流了细节

6、可改进点:
邮件的地址内容显示的是一个列表,有待改进。

7、github对应仓库:

https://github.com/vansnowpea/WestWorld-auto-download-email-xunlei-

8、推荐 xpath学习教程:

http://zvon.org/xxl/XPathTutorial/General_chi/examples.html

国外最新高清pdf寻找以及实现迅雷自动下载【Python】

Veröffentlicht am 2016-10-11

国外最新高清pdf寻找以及实现迅雷自动下载

1、今天意外发现国外某站,提供非常近期,甚至国内亚马逊还没上市的最新高清pdf,所以测试爬虫,看是否能自动下载。

2、

《OReilly.Introduction.to.Machine.Learning.with.Python.A.Guide.for.Data.Scientists.1449369413》

一开始人工下载成功, 国内要月底才上线呢。

3、 随后测试程序是否可自动下载,第二本书的下载遇到了问题:总提示服务器维护,但更换了ip也这样的结果,后发现是对应网盘异常了。

4、代码:

# -*- coding: utf-8 -*-
# python 3.5.2
# 测试系统,Win10,Firefox V46
# Author:Van
# 实现自动下载高清最新pdf的实现
# V1.0 当前只针对效果还可以的国外zippyshare网盘
# 其他的网盘还没添加进判断语句,先共享如何迅雷下载等
# 如果您有经验优化,改进此脚本,请不吝指教
# QQ群: 206241755
# 简介:因下载最新高清pdf,正好发现www.foxebook.net提供
# 但是很多的广告,特烦人,所以尝试脚本,最后因下载需求,
# 加载了迅雷,这功能的实现小牛,不过也是网络别人共享的。。

from selenium import webdriver
import requests
from lxml import etree
import re
import os
from win32com.client import Dispatch



#test name of book : SciPy and NumPy
# book_name = input('Please input the book name in English:\n')
book_name = 'Introduction to Machine Learning with Python'
print ('begin to search book(s)...')
print ('---------------------------------')
# search link is :http://www.foxebook.nethttp://www.foxebook.net/search/SciPy%20and%20NumPySciPy%20and%20NumPy
PostUrl = "http://www.foxebook.net/search/" + book_name
# print(PostUrl)
# get the content of html
html = requests.get(PostUrl).content

# use etree selector
selector = etree.HTML(html)

# /html/body/div/div/main/div[2]/div[2]/h3/a
# /html/body/div/div/main/div[3]/div[2]/h3/a
# above is two books' xpath, so the right xpath for all book is :
# /html/body/div/div/main//div[2]/h3/a
# it can be confirmed by 'xpath checker'
total_books = selector.xpath("/html/body/div/div/main//div[2]/h3/a/text()")
# print('total books from searching are:', total_books)

num1 = 0
link_address = []
real_address = []
def find_link():
    global num1
    # find the right book, put all links in a list of : link_address

    for i in total_books:
        num1 += 1
        if re.search(book_name,i):

            print('Congrdulations, we find the book(s):\n')
            print ('**********************************')
            print(i)
            print ('**********************************\n')
            href = 'http://www.foxebook.net' + selector.xpath('//*[@id="content"]/div/main/div[%d]/div[2]/h3/a/@href'%num1)[0]
            # print('the book link is :', href)
            # print('will downloading...')
            html_new = requests.get(href).content
            selector_new = etree.HTML(html_new)
            link_new = selector_new.xpath('//*[@id="download"]/div[2]/table/tbody/tr[1]/td[2]/a/@href')[0]
            # split the next link
            link_new = 'http:'+link_new.split(':')[-1]
            link_address.append(link_new)
    print('download link is :', link_address)
    print('\n\n')

def real_book_link():
    # print('link_address is :', link_address)
    # dynamic on zippyshare
    for j in link_address:
        # 用浏览器实现访问

        driver = webdriver.Firefox()
        driver.maximize_window()
        driver.get(j)


        try:

            # find the download button
            title_list = driver.find_element_by_xpath('//*[@id="dlbutton"]')
            film_link = title_list.get_attribute('href')
            real_address.append(film_link)

        except:
            print('can not download the book')

    print('real_book_link:', real_address)
    return real_address

def addTasktoXunlei(down_url,course_infos):
    flag = False
    o = Dispatch("ThunderAgent.Agent.1")
    if down_url:
        course_path = os.getcwd()
        try:
            #AddTask("下载地址", "另存文件名", "保存目录","任务注释","引用地址","开始模式", "只从原始地址下载","从原始地址下载线程数")
            o.AddTask(down_url, '', course_path, "", "", -1, 0, 5)
            o.CommitTasks()
            flag = True
        except Exception:

            print(Exception.message)
            print(" AddTask is fail!")
    return flag

if __name__ == '__main__':
    find_link()
    real_link = real_book_link()
    for i in real_link:
        addTasktoXunlei(i, course_infos=None)

5、第二天分析:
更换下载的书名为:《Introduction to Machine Learning with Python》

得到了2个有效的书籍目录,对比昨天的书籍名,发现提供的下载源是不同的国外网盘,而昨天的那个到今天一直打不开,而这本书的网址很快就打开了,网盘名字为: zippyshare.com

然后研究了下,此foxebook.net站点提供的一些网盘下载使用了多家国外网盘,并且各家的广告显示不尽相同,可靠性更是差别较大。

另外,发现,就SciPy and NumPy一书来说,他最后得到的地址有2个http,这应该是广告模式,而后者的http的内容是我们真实需要的,所以通过冒号:来切分a.split(‘:’)[-1]。

In [10]: a = 'http://sh.st/st/7a45e8ed9f73a6a10e9a22b2d8783c44/http://www65.zippyshare.com/v/oFSWQWDk/file.html'

In [11]: a
Out[11]: 'http://sh.st/st/7a45e8ed9f73a6a10e9a22b2d8783c44/http://www65.zippyshare.com/v/oFSWQWDk/file.html'

In [12]: a.split(':')[-1]
Out[12]: '//www65.zippyshare.com/v/oFSWQWDk/file.html'

6、忘记说明下昨天的代码为何要用re.match (或者re.research), 这是因为网站的关键词搜索引擎所使用的算法,我们是不知道的,但从搜索结果看,某关键词下,可能有不同的书籍,而我们是需要精确搜索,下图中实际出现了16本书,但针对SciPy and NumPy,我们要找的是第三个图对应的。因此,我们可以把显示的书名做一个match对照的循环,来实现精确匹配。而另外一方面,网站提供的书名还可能多了冒号,后面附加书名,这样的也符合我们的要求。后来发现用关键词 if xxx in yyy的方式更简便。

7、昨天的代码一开始没有考虑到国外网盘下载异常失败的问题,并且有的搜索结果可能有多个网盘地址,而我只取了默认的第一个,考虑到下载的失败可能性,最好把所有下载地址都获取。所以代码需要修改。
由于:SciPy and NumPy 对应的网盘当机,选用:《Introduction to Machine Learning with Python》为例

经过对照,在最后的下载界面,是动态的,因此调用selenium+Firefox组合。最后终于得到了完整pdf队中的链接,但速度明显比较慢了,在本例中,是rar后缀的压缩包格式,里面含有pdf。

download link is : ['http://www78.zippyshare.com/v/hBU7JYZp/file.html', 'http://www65.zippyshare.com/v/oFSWQWDk/file.html']



content: 
book link: http://www78.zippyshare.com/d/hBU7JYZp/2248094/OReilly.Introduction.to.Machine.Learning.with.Python.A.Guide.for.Data.Scientists.1449369413.rar
content: 
book link: http://www65.zippyshare.com/d/oFSWQWDk/1124867/OReilly.Introduction.to.Machine.Learning.with.Python.1449369413_Early.Release.rar

Process finished with exit code 0

8、接下来的一个问题,怎么让程序自动下载这2个链接?群里有人推荐了一些别的软件,但是我想来想去因为以后总要面对下载速度的问题,还是选定了迅雷破解版吧,除非将来有其他更好的方案,好在有人共享了一个方案,还特别简单,不过据说只能支持http格式,BT格式的以后再想办法。

9:补充说明,在正文代码的第2个下载地址,是有问题的,差别在于地址点击后,前者可在浏览器或者迅雷直接下载,而后者浏览器没反映,迅雷里下载的是一个html。尽管2个链接的提取方法完全一样,但一个好使,一个异常,由于是同一本书的前后2个小版本,我也不管他了,但为了验证迅雷是否能同时下载5个(代码里设定同时下载的最大值,也是一般默认值) 我用额外的测试脚本加载了一个新的链接,是证明可同时下载的,如图:

9、参考:

http://neue.v2ex.com/t/275703

10、github对应仓库:

https://github.com/vansnowpea/download-pdf-with-Xunlei

用户细分精准营销--聚类 以及 机器学习典型应用【Python】

Veröffentlicht am 2016-10-10

用户细分精准营销–聚类

1、中国移动的各个手机套餐之间的分类为例:

  • 动感地带: 目标群:在校学生,短信需求旺盛,短信费用低。
  • 神州大众卡:目标群:更多客户,四川移动推出:最让消费者动心的是没有月租费的日子里接听网内来电20元包完。
  • 全球通: 目标群:全球飞的高端上午人群,不是很在乎话费,却关心品牌的增值服务,如vip候机厅等。
  • 神州行: 目标群:普通务工人员,电话需求较多,通话费用低。

那么在那个还没有智能机的年代,他们是怎么想到这些分类方法或者区分客户群的呢?回头想来客户群的区分有相当比例是由客户自己定义使用哪个套餐的。当然,以现在的技术用计算机AI可以相对容易的来进行聚类区分了。


反垃圾邮件:  朴素贝叶斯

信贷风险控制:  决策树

互联网广告:  ctr预估-线性逻辑回归

推荐系统:  协同过滤

自然语言处理:  情感分析,实体识别

图像识别:  深度学习

其他


一些常用的算法分类表:

  • C4.5 是决策树算法,可以解决分类和回归问题,又属于有监督算法
  • K-Means 是聚类算法,无监督。
  • SVM: 基于统计学,有完整理论。
  • PageRank:谷歌的算法

机器学习的框架

训练模型:

1、定义模型

2、定义损失函数

3、优化算法

模型评估:

1、交易验证

2、效果评估

数据分析的参考书集锦【Python】+【R】

Veröffentlicht am 2016-10-08

数据分析的参考书集锦,先保存过来再说。

原文: http://bbs.pinggu.org/thread-3116701-1-1.html

入门读物:

深入浅出数据分析 这书挺简单的,基本的内容都涉及了,说得也比较清楚,最后谈到了 R 是大加分。难易程度:非常易。
啤酒与尿布 通过案例来说事情,而且是最经典的例子。难易程度:非常易。
数据之美 一本介绍性的书籍,每章都解决一个具体的问题,甚至还有代码,对理解数据分析的应用领域和做法非常有帮助。难易程度:易。
数学之美 这本书非常棒啦,入门读起来很不错!
下载地址:深入浅出数据分析、啤酒与尿布、数据之美、数学之美。

数据分析:

SciPy and NumPy 这本书可以归类为数据分析书吧,因为 numpy 和 scipy 真的是非常强大啊。
Python for Data Analysis 作者是 Pandas 包的作者,看过他在 Scipy 会议上的演讲,实例非常强!
Bad Data Handbook 很好玩的书,作者的角度很不同。
下载地址:SciPy and NumPy、Python for Data Analysis、Bad Data Handbook

适合入门的教程:

集体智慧编程 学习数据分析、数据挖掘、机器学习人员应该仔细阅读的第一本书。作者通过实际例子介绍了机器学习和数据挖掘中的算法,浅显易懂,还有可执行的 Python 代码。难易程度:中。
Machine Learning in Action 用人话把复杂难懂的机器学习算法解释清楚了,其中有零星的数学公式,但是是以解释清楚为目的的。而且有 Python 代码,大赞!目前中科院的王斌老师(微博: 王斌_ICTIR)已经翻译这本书了 机器学习实战 。这本书本身质量就很高,王老师的翻译质量也很高。难易程度:中。我带的研究生入门必看数目之一!
Building Machine Learning Systems with Python 虽然是英文的,但是由于写得很简单,比较理解,又有 Python 代码跟着,辅助理解。
数据挖掘导论 最近几年数据挖掘教材中比较好的一本书,被美国诸多大学的数据挖掘课作为教材,没有推荐 Jiawei Han 老师的那本书,因为个人觉得那本书对于初学者来说不太容易读懂。难易程度:中上。
Machine Learning for Hackers 也是通过实例讲解机器学习算法,用 R 实现的,可以一边学习机器学习一边学习 R。
下载地址:集体智慧编程+源代码、Machine Learning in Action、Building Machine Learning Systems with Python、 数据挖掘导论、Machine Learning for Hackers

稍微专业些的:

Introduction to Semi-Supervised Learning 半监督学习必读必看的书。
Learning to Rank for Information Retrieval 微软亚院刘铁岩老师关于 LTR 的著作,啥都不说了,推荐!
Learning to Rank for Information Retrieval and Natural Language Processing 李航老师关于 LTR 的书,也是当时他在微软亚院时候的书,可见微软亚院对 LTR 的研究之深,贡献之大。
推荐系统实践 这本书不用说了,研究推荐系统必须要读的书,而且是第一本要读的书。
Graphical Models, Exponential Families, and Variational Inference 这个是 Jordan 老爷子和他的得意门徒 Martin J Wainwright 在 Foundation of Machine Learning Research 上的创刊号,可以免费下载,比较难懂,但是一旦读通了,graphical model 的相关内容就可以踏平了。
Natural Language Processing with Python NLP 经典,其实主要是讲 NLTK 这个包,但是啊,NLTK 这个包几乎涵盖了 NLP 的很多内容了啊!
下载地址:Introduction to Semi-Supervised Learning、Learning to Rank for Information Retrieval、 Learning to Rank for Information Retrieval and Natural Language Proces、推荐系统实践

机器学习教材:
The Elements of Statistical Learning 这本书有对应的中文版:统计学习基础 。书中配有 R 包,非常赞!可以参照着代码学习算法。
统计学习方法 李航老师的扛鼎之作,强烈推荐。难易程度:难。
Machine Learning 去年出版的新书,作者 Kevin Murrphy 教授是机器学习领域中年少有为的代表。这书是他的集大成之作,写完之后,就去 Google 了,产学研结合,没有比这个更好的了。
Machine Learning 这书和上面的书不是一本!这书叫:Machine Learning: An Algorithmic Perspective 之前做过我带的研究生教材,由于配有代码,所以理解起来比较容易。
Pattern Recognition And Machine Learning 经典中的经典。
Bayesian Reasoning and Machine Learning 看名字就知道了,彻彻底底的 Bayesian 学派的书,里面的内容非常多,有一张图将机器学习中设计算法的关系总结了一下,很棒。
Probabilistic Graphical Models 鸿篇巨制,这书谁要是读完了告诉我一声。
Convex Optimization 凸优化中最好的教材,没有之一了。课程也非常棒,Stephen 老师拿着纸一步一步推到,图一点一点画,太棒了。
下载地址:The Elements of Statistical Learning、统计学习方法、Machine Learning: An Algorithmic Perspective、
Pattern Recognition and Machine Learning+答案、Bayesian Reasoning and Machine Learning、 Probabilistic Graphical Models、Convexity and Optimization

下载最新电影的爬虫---Xpath读取文本,链接,标题等的操作【Python】

Veröffentlicht am 2016-10-07

下载最新电影的爬虫

1、使用:

  • lxml.etree
  • requests

2、代码:

# -*- coding:utf-8 -*-
import requests
from lxml import etree


url = 'http://www.ygdy8.net/html/gndy/dyzz/index.html'  #这是电影最新电影的网站
# r = requests.get(url).content
# print(r.encoding)
# >>> ISO-8859-1
html = requests.get(url).content
# html = requests.get(url).content.decode('ISO-8859-1').encode('utf-8')

selector = etree.HTML(html)

# //*[@id="content"]/div/div[1]/ol/li[1]/div/div[2]/div[2]/p[1]
# get rid of the : /tbody
biaoti = selector.xpath('//*[@id="header"]/div/div[3]/div[3]/div[2]/div[2]/div[2]/ul//tr[2]/td[2]/b/a/text()')


# get rid of the : /tbody
jianjie = selector.xpath('/html/body/div/div/div[3]/div[3]/div[2]/div[2]/div[2]/ul//tr[4]/td/text()')
wangzhi = selector.xpath('//*[@id="header"]/div/div[3]/div[3]/div[2]/div[2]/div[2]/ul//tr[2]/td[2]/b/a/@href')

for b,j,k in zip(biaoti,jianjie,wangzhi):
    print(b+'\n'+j+'\n'+'www.ygdy8.net'+k+'\n')

3、分析:主要和上一篇的接近,但是这一篇还有读取网址等操作,注意格式上和读取内容text有差别的。
总结如下:

获取到标签后我们可以获取标签中的属性值
tree.xpath("//div[@class='sec_blk mrg_b_30']/ul/li[1]/a/text()")     #获取a的文本,li标号是从1开始,而不是从0开始
tree.xpath("//div[@class='sec_blk mrg_b_30']/ul/li[1]/a/@href")   #获取a的链接地址

当然还有其他类似的xpath例子:
"//input[@id='city']/@value"
"//div[@class='venueDetal']/p/img[@class='img']/@src"
"//div[@class='detail_info_title']//a[@class='hotel_star']/@title"

4、参考: python+lxml xpath获取数据

5、可补充点: 自动提取直接下载链接,看是否能导入到迅雷等工具。

东方财富网cpi数据的抓取【Python】

Veröffentlicht am 2016-10-07

东方财富网cpi数据的抓取

1、使用:

  • lxml.etree
  • requests

2、代码:

from lxml import etree
import requests

url = 'http://data.eastmoney.com/cjsj/cpi.html'
content = requests.get(url).content

html = etree.HTML(content)
content1 = html.xpath('//*[@id="tb"]/tr[3]/td[2]/text()')

print(content1[0].strip().replace('\n\r', ''))

# for txt in html.iterfind('.//*[@id="tb"]/tr[3]/td'):
#     print(txt.text)

3、分析:requests+lxml来分析和提取数据比较简单,可以尽可能的规避使用RE的复杂性以及可能产生的编码问题。要注意的是提取文本内容的时候要在xpath地址后面加上/text()
不过这个案例中,需要把xpath的/tbody去掉,这是因为有的浏览器加上去的,否则不能识别需要的文字部分。
另外,默认的结果因为有很多的空格和\n\r,所以需要做数据清洗,就本例,加一句content1[0].strip().replace(‘\n\r’, ‘’)即可。

4、没有执行的代码,表示读取2016年08月份 “全国”,“城市”,“农村”各自的cpi数据。
要注意的是:这属于ElementPath,一共4个种类,分别如下:

  1. iterfind()
  2. findall()
  3. find()
  4. findtext()

千万注意的是:ElementPath不能直接使用绝对路径,需要在前面加一个.符号。暂时感觉这个使用的不太多。

123…8
Van

Van

71 Artikel
© 2017 Van
Erstellt mit Hexo
Theme - NexT.Muse