Category: Coding

十一月 25th, 2015 by lanxinxichen@126.com

目标:在不删除python环境的情况下,安装一些常用的python库到windows中。

安装

VCForPython27 :windows下面vc库的安装软件。

Numpy : numpy windows下面的exe文件

scipy : scipy 的exe文件

matplotlib : pip 环境下的 whl 安装包,需要使用pip install 这个文件.whl 安装

 

下面工具还不熟悉,先不写描述了。

setuptools

python_dateutil

pyparsing

 

 

 

Posted in Python, 机器学习 Tagged with: ,

十一月 24th, 2015 by lanxinxichen@126.com

最近做项目使用scrapy,采用的是script的形式去写爬虫的,使用crawlspider去定义爬虫规则。
我先从数据库里面把我要读取的规则拿出来,采用的是单个频道写规则的形式,对每个列表页写一套规则,所以有next_page的规则。

sql = """SELECT id, weburl_id, name, allow_domains, start_urls, next_page,
      allow_url, extract_from, title_xpath, body_xpath, publish_time_xpath, source_site_xpath, enable
      FROM leiju_rules WHERE enable > 0"""

next_page分析形式是xpath提取链接,使用Rule不跟随(follow = False)。我的需求是我应该采集所有的页面,但是由于我想做成定时任务,就需要下次还使用这一套规则来运行爬虫,做到增量爬。这样的话就涉及到了内容的去重。开发的最开始,我才用的是pipline 通道去重,也就是当我产生一个request之后才开始判断这个内容我需要不需要,这样是很浪费服务器资源的。

if self.Redis.exists('url:%s' % item['url']):
    raise DropItem("Duplicate item found: %s" % item['url'])
else:
    self.Redis.set('url:%s' % item['url'], 1)
    return item

然后我修改成采用downloadMiddleware下载中间件去控制访问,因为downloadMiddleware是可以控制在request访问之前的,加上Redis的过滤。

if Redis.exists('url:%s' % response.url):
    raise IgnoreRequest("IgnoreRequest : %s" % response.url)
else:
    Redis.set('url:%s' % response.url, 1)
    return response

这时候又有一个问题了,就是我会把所有的访问都给记录下来,下次我连我写的起始start_urls都进不去了。本来寄托于从以下代码入手:

rule_list.append(Rule(LinkExtractor(restrict_xpaths=rule['next_page'])))

即希望通过next_page拿到下一页的链接,然后把这些链接排除掉,已经准备好了一个Redis库去存储这些url。

Filter = redis.StrictRedis(host='127.0.0.1', port=6379, db=2, password='pass123456')

然而实际在使用的时候发现我通过:

rule_list.append(Rule(LinkExtractor(restrict_xpaths=rule['next_page'])))

拿到的根本不是URL列表,而是一个Rule对象,里面包括了LinkExtarctor的Xpath规则。我甚至想通过response和xpath拿到链接之后在用redis存起来进行排除。
 
解决方法:
配合使用pipline和downloadMiddleware来轻松完成以上功能。
我先定义一个downloadMiddleware,用来拦截url,防止重复访问。

class IngoreHttpRequestMiddleware(object):
    """ 从下载器处开始拦截/过滤URL """
    def process_response(self, request, response, spider):
        if Redis.exists('url:%s' % response.url):
            raise IgnoreRequest("IgnoreRequest : %s" % response.url)
        else:
            # Redis.set('url:%s' % response.url, 1)
            return response

然后定义一个pipline,用来保存最终流入pipline的item URL。

class FilterUrlPipline(object):
    """ use redis to fileter url """
    def __init__(self):
        self.Redis = config.Redis

    def process_item(self, item, spider):
        self.Redis.set('url:%s' % item['url'], 1)
        return item

这样一来,我的一个列表页面的所有链接都进入到了downloadMiddleware中,但是通过pipline拿到了最终我要的终极页面,通过pipline保存item URL,然后下次的时候redis里面有了数据,就可以排除所有的符合的终极页面访问请求,这样就解决了。
 
已开源在github上面:https://github.com/fengxiaochuang/ScrapyDemo

Posted in Python Tagged with: , , ,

十一月 9th, 2015 by lanxinxichen@126.com

最近做项目使用了whoosh+flask,因为flask使用的是jinjia2 模板引擎,所以就此遇到的html转义的问题做一个解释.

以上为背景.

 

使用whoosh+falsk搜索的时候,我采用的是关键词高亮显示,但是在实际操作的过程中,生成的html是带<b></b>标签的字符串,无论怎样,这个标签字符串总是显示在html页面中.

开始我以为是因为在输出的过程中转义有问题,所以搜索python的html转义方法.无论正转义还是反转义,结果都不行.

QQ截图20151109123714

 

开始后来渐渐怀疑到jinjia2模板引擎上面,我从一开始已未需要加参数 “|e” 调试仍然不行,后来继续搜close escape html 才发现有一个safe参数,能够保证原始的 string 就不会被escape,修改后

{{ row.hit_title|safe }}

QQ截图20151109125754

终于,html标签不再显示为字符串了

Posted in Python Tagged with: , ,

十一月 4th, 2015 by lanxinxichen@126.com

从whoosh的坑里爬出来了,简单介绍一下实用搜索方面的内容,之前绕路了,希望以后学习的人不会绕远路.既然讲的话,就从我的一路的坑细细数来吧.

首先是受到whoosh官方demo的影响,我以为只能使用关键词的搜索,所以我用的如下方法:

for keyword in ("水果世博园", "你", "first", "中文", "交换机", "交换"):
    print("result of ", keyword)
    q = parser.parse(keyword)
    results = searcher.search(q)
    for hit in results:
        # print(hit.highlights("content"))
        print(hit)

当然这样的话搜索出来的结果都是每个关键词对应的一个搜索列表.这时候我甚至一度怀疑whoosh不支持短语的搜索,因为害怕自己去写搜索算法,于是此事搁置.

今天早上忽然有想到这个问题了,继续搜相关内容,无意中看到csdn上面有一篇文章提到Or Term And这种关键词,终于又回到whoosh手册上面了…真的是想要学一门技术就去读它的手册,上次吃亏在scrapy的logging上面…

然后开始进行程序改造,搜索短语,比如搜索:”中国国际物流节开幕”,采用结巴分词,先把这句话分解成一个个的关键词.

inputstring = "中国国际物流节开幕"
keywords = []
for t in analyzer(inputstring):
    keywords.append(t.text)

拆开的关键词是:中国 国际 物流 国际物流节(我自己添加到jieba字典里面的) 开幕

然后采用各种手册上面的iter_all_terms terms方法,不行,然后继续看手册,发现其实parse默认的标准是采用的And,而且我搜索的字段是body,而这句话是我从title里面复制出来的,自然返回为空了.

知道了基本原理就先通过修改Term进行测试:

And([Term("title", "中国"), Term("title", "国际"), Term("title", "物流"), Term("title", "国际物流节"), Term("title", "开幕")])

通过该And和Or来调解Trem去测试搜索结果,总体来看基本思路是对的.

Or([Term("title", "中国"), Term("title", "国际"), Term("title", "物流"), Term("title", "国际物流节"), Term("title", "开幕")])

通过上面的querystring 终于搜索出来结果了…

那么既然结果出来了,下一步就是继续给搜索添加条件了,类似谷歌的搜索是如何做到的呢?于是我再google上面搜索”whoosh like search google”

然后在stackoverflow上面搜索出来答案了,给出的几个选择pyl,pyprasing等…然后继续搜索whoosh和pyprasing,搜索出来的代码都是在whoosh,support.pyprasing下面调用的,我import没有啊,继续看搜索结果,,,看到whoosh里面有这么一句话:(In previous versions of Whoosh, the query parser was based on pyparsing. The new hand-written parser is less brittle and more flexible.)

你说什么!whoosh原本就是基于pyparsing构造语法的?往下看手册,,,真的是必须硬着头皮看手册啊….

发现whoosh本身支持通过” “(空格)来分割关键词搜索的.也是支持and or 这种直接的搜索语法的,还可以自己定义这些逻辑符号.

再往下就顺利多了,随便贴一点我用到的关键代码把:

inputstring = "中国and(国际or物流)and开幕"
qp = MultifieldParser(["title", "body"], schema=ix.schema)
    querystring = qp.parse(inputstring)
    results = searcher.search(querystring, terms=True, limit=100, collapse_limit=1)
    for hit in results:
        print(hit['title'].encode('gbk'))

RTFM!

RTFM!

RTFM!

Posted in Python Tagged with: ,

八月 25th, 2015 by lanxinxichen@126.com

今天在处理ecshop计划任务的时候,发现怎样都无法执行,而且由于重写了header头,导致一直获取不到错误信息,使用file_put_content() 函数一直跟踪代码,一直发现cron.php文件57行开始有以下代码:

$f_info = parse_url($_SERVER[‘HTTP_REFERER’]);
$f_now = basename($f_info[‘path’]);

$f = explode(‘ ‘, $cron_val[‘alow_files’]);
if (!in_array($f_now, $f))
{
continue;
}

也就是说如果访问链接不包含在设定的访问链接里面的时候,就跳出该循环.

而开启了url重写之后的$f_now为 XXXXX_156.html 自然匹配不到XXXX.php的$crom_val[‘alow_files]之中去.

添加一段兼容代码即可解决问题:

// 由于原本的计划任务不支持url重写,这里添加判断兼容代码
if (strstr($f_now,’html’)) {
$url = explode(‘-‘,$f_now);
$f_now = $url[0].’.php';
}

把html的链接转化成.php的文件,然后重新重新判断访问来源是不是在设定的触发页面之中,经过测试,顺利执行!

Posted in PHP Tagged with: , ,

七月 7th, 2015 by lanxinxichen@126.com
升级命令wget http://down.wdlinux.cn/in/mysql_up55.sh
sh mysql_up55.sh

今天升级mysql5.5 结果发现怎么都启动不起来
错误情况
http://www.wdlinux.cn/bbs/viewthread.php?tid=5137
安装完后提示
1.png

重启mysql时提示,后台登陆不了。
2.png

解决办法

3.png

vi /www/wdlinux/init.d/mysqld
修改46 47行的目录为安装目录与数据库目录
4.png

5.png

 

原文链接:http://www.wdlinux.cn/bbs/thread-5461-1-1.html

Posted in PHP, 数据库

六月 10th, 2015 by lanxinxichen@126.com

ECharts

百度 (中文) : http://echarts.baidu.com

在线视频教程:http://study.163.com/course/courseMain.htm?courseId=1016007

Why ECharts (中文) : http://echarts.baidu.com/doc/slide/whyEcharts.html

Github pages (English) : http://ecomfe.github.io/echarts/index-en.html

Why ECharts (English) : http://ecomfe.github.io/echarts/doc/slide/whyEcharts-en.html

基于Canvas,纯Javascript图表库,提供直观,生动,可交互,可个性化定制的数据可视化图表。创新的拖拽重计算、数据视图、值域漫游等特性大大增强了用户体验,赋予了用户对数据进行挖掘、整合的能力。

ECharts (Enterprise Charts 商业产品图表库)

提供商业产品常用图表库,底层基于ZRender,创建了坐标系,图例,提示,工具箱等基础组件,并在此上构建出折线图(区域图)、柱状图(条状图)、散点图(气泡图)、饼图(环形图)、K线图、地图、和弦图以及力导向布局图,同时支持任意维度的堆积和多图表混合展现。

(IE8- supported by excanvas )

ECharts Architecture

 

正文:

制作一个时间轴的图标,基于echarts.js的不等距折线图:参照demo:http://echarts.baidu.com/doc/example/line8.html

核心代码:part1part2

 

图中所用的是测试数据,采用的new Date生成的随机数,用来模拟图表.然而一般从台传输过来的数据一般都是时间戳或者是其他时间类型的字符串.可以采用如下方式

 

part3

通过后台传入过来的json字符串,然后前台进行数据的处理,处理成一个时间对象的元素.

这样就能保证数据能够识别time类型的了.

echartdemo

Posted in JavaScript Tagged with: , ,

五月 26th, 2015 by lanxinxichen@126.com

在做第三方接口对接的时候,有些数据返回的都是json字符串,所以在处理的时候,有时候需要将json字符串给存到数据库中,因为在ecshop 中全部用的都是sql语句插入的,所以有时候json字符串中有一些非法字符,会吧sql语句给中断,比如”()”这种.

为了避免出现这种问题,使用mysql_real_escape_string函数给转化成对数据库安全的字符串.

然而在转化的时候,把一些不希望存入数据库的一些字符串页给转化了一下.之后在用explore处理该字符串的时候,一直报错,并且看到的字符串是乱码的.

开始以为是编码方式和字符集的问题,于是使用iconv 和mb_detect_encoding mb_convert_encoding 去转化,都无法生效,同样的explore也无法分割.直到发现是mysql_real_escape_string的原因…

所以转移字符并不是什么地方都可以使用的.

Posted in 数据库 Tagged with: , , ,

五月 26th, 2015 by lanxinxichen@126.com

今天在处理第三方接口的时候,返回的json数据怎样decode都是null,但是通过打印返回的json字符产,确实可以看出来是返回数据了.

通过json_last_error 返回4,即

JSON_ERROR_SYNTAX 语法错误

网上传言可能出现的问题:

1. json字符串必须以双引号包含

$output = str_replace(“‘”, ‘”‘, $output);

2. json字符串必须是utf8编码
$output = iconv(‘gbk’, ‘utf8′, $output);

3.不能有多余的逗号 如:[1,2,]
用正则替换掉,preg_replace(‘/,\s*([\]}])/m’, ‘$1′, $output)

 

然而并没有解决问题.

继续搜索发现说是有一些字符混在在json数据中,把这些字符替换掉,就可以了.

<?php
$checkLogin = file_get_contents("http://yourwebsite.com/JsonData");

// This will remove unwanted characters.
// Check http://www.php.net/chr for details
for ($i = 0; $i <= 31; ++$i) { 
    $checkLogin = str_replace(chr($i), "", $checkLogin); 
}
$checkLogin = str_replace(chr(127), "", $checkLogin);

// This is the most common part
// Some file begins with 'efbbbf' to mark the beginning of the file. (binary level)
// here we detect it and we remove it, basically it's the first 3 characters 
if (0 === strpos(bin2hex($checkLogin), 'efbbbf')) {
   $checkLogin = substr($checkLogin, 3);
}

$checkLogin = json_decode( $checkLogin );
print_r($checkLogin);
?>

origin:http://stackoverflow.com/questions/17219916/json-decode-returns-json-error-syntax-but-online-formatter-says-the-json-is-ok

Posted in PHP Tagged with: ,

五月 21st, 2015 by lanxinxichen@126.com

第一步:

\admin\includes\inc_menu.php 添加 一个菜单项对应的路径

例如: $modules[’16_email_manage’][‘view_sendlist’]        = ‘view_sendlist.php?act=list';  前面的数组是排序需要的,后面的email_manage 是一级菜单 view_sendlist 是二级菜单  ‘view_sendlist.php?act=list’是后台代码指向位置

第二步:

admin\includes\inc_priv.php 添加一个菜单项的别名

第三步:

languages\zh_cn\admin\common.php 添加公共语言包中别名对应的汉字

这里是简体中文,如果想完善,需要同时添加英文和繁体中文.

第四步:

anguages\zh_cn\admin\priv_action.php 添加权限文件中的别名对应的文字

同上 可以设置英文和繁体中文

第五步:

数据表 ecs_admin_action 添加数据 将权限跟action关联起来

第六步:

对应的zh_cn/log_action.php中添加相应的操作记录日志语言:

$_LANG[‘log_action’][‘content’] = ‘XX管理';

 

Posted in PHP Tagged with: ,