2018年4月

以为省市区县镇村这样的名字组成的字典会有现成的下载,结果比想的要复杂,只能自己去提取。
在网上下来了一个到处的sql文件,导入到本地的mysql数据库,接下来的思路就是distict对应的字段,然后逐行写入到字典文件。
在python下完成。

安装PyMySQL包

安装python的开发环境就不说了,我是用的PyCharm,之前研究了如何使用,因此安装一个依赖包的操作还比较简单。

遇到了一个坑:中文乱码

中文乱码多半是因为数据集的原因,只要把数据库和数据表的字符集修改为utf8,以及客户端的字符集修改为utf8
解决python中mysql查询中文乱码的问题
显示数据库字符集

show variables like 'character%'

设置字符集

set character_set_server =utf8

导出字典的部分代码如下:

import pymysql

class AnManMysql:
    phost = '127.0.0.1'
    pyuer = 'root'
    password = '123456'
    database = 'anman_org'
    def pyMyConnection(phost,pyuser,password,database):
        db = pymysql.connect(phost,pyuser,password,database,charset="utf8")
        cursor = db.cursor()
        return cursor

    # 导出省市县镇村字典
    def getDict(cursor):
        cursor.execute("select distinct province_name from j_position")
        data = cursor.fetchall()
        # 打开字典文件my.dict
        fo = open("my.dict","w+")
        for da in data:
            print(da[0])
            fo.seek(0,2)
            fo.write(da[0]+"\n")
        print(len(data))
        cursor.execute("select distinct city_name from j_position")
        data = cursor.fetchall()
        for da in data:
            print(da[0])
            fo.seek(0, 2)
            fo.write(da[0] + "\n")
        print(len(data))
        cursor.execute("select distinct county_name from j_position")
        data = cursor.fetchall()
        for da in data:
            print(da[0])
            fo.seek(0, 2)
            fo.write(da[0] + "\n")
        print(len(data))
        cursor.execute("select distinct town_name from j_position")
        data = cursor.fetchall()
        for da in data:
            print(da[0])
            fo.seek(0, 2)
            fo.write(da[0] + "\n")
        print(len(data))
        cursor.execute("select distinct village_name,village_id from j_position")
        data = cursor.fetchall()
        for da in data:
            print(da[0])
            print(da[1])
            fo.seek(0, 2)
            fo.write(da[0] + "\n")
        print(len(data))
        fo.close()

cursor = AnManMysql.pyMyConnection(AnManMysql.phost, AnManMysql.pyuer, AnManMysql.password, AnManMysql.database)
AnManMysql.getProvinceDict(cursor)

最终得到的字典文件,大约10M,一共703205行

在开发失踪儿童信息平台的过程中,关于数据采集,经理过两个版本,第一个版本中,是通过浏览器+js+服务端相结合的方式把数据采集到本地数据库;在第二个版本中,则改为后台进程的方式进行数据采集。

第一版,通过chrome浏览器扩展实现js注入,采集数据

这是在2017年最开始做采集的一个方案,具体来说就是通过Chrome浏览器浏览页面,自己写一个扩展,在页面中实现js注入,通过js来处理前端的数据,然后将数据post提交到服务器端,将数据保存在指定的数据库里面。
这种采集方法,非常的稳定,打开浏览器,就是自动的浏览,换页。也很简单的实现跨平台,linux或者windows系统,只有安装chrome浏览器就可以开始采集。
但是对数据源端依赖很大,比如后来淘宝将这个接口关闭之后,就采集不了了。
所以,第一版的采集方案基本上是一次性的,基于客户端的。

第二版,服务端采集程序

也就是今天要说的这个采集程序。使用的是PHP语言,而框架则是选择的MixPHP,一个基于 Swoole 的常驻内存型 PHP 高性能框架。而Swoole则是拓展了 PHPer 的能力范围,不再局限于Web开发、短生命周期、同步阻塞。
开始开发之前,可以根据MixPHP的官方文档进行准备,作者写的非常详细,有关Swoole扩展的安装则可以到Swoole的官方文档中找到。
框架安装好之后,可以根据文档中介绍的内容开始daemon程序开发,daemon是Console应用,通过shell命令执行。
apps->daemon->commands目录下新建一个控制器IndexController.php,这个控制器可以作为入口文件被找到。
要实现无人监督方式的采集,大体需要实现如下功能:

  1. 批量采集
  2. 增量采集
  3. 实时采集

在程序第一次运行时,需要根据给定的种子url批量的采集一次,这个起到数据初始化的作用。
由于儿童失踪信息的状态会变化,在状态发生变化时要及时采集
新的儿童失踪信息会产生,因此要做增量采集。

class IndexController extends Controller
{
public function actionIncrement(){...}
public function actionRecheck(){...}
public function actionBatch(){...}
public function actionDetail(){...}
}

初始化运行命令行:./mix-daemon index/batch
增量采集运行:./mix-daemon index/increment
实时检查状态变化运行./mix-daemon index/recheck

基于Swoole可以作为后台程序运行,因此在服务器上执行上述命令后,系统将自动采集,无需人工干预。

冒泡排序的小程序,用python来实现

class BubbleSortClass:
    # 排序
    def bSort(bubbleList):
        for i in range(len(bubbleList) - 1):
            for j in range(len(bubbleList) - 1 - i):
                if bubbleList[j] > bubbleList[j + 1]:
                    bubbleList[j], bubbleList[j + 1] = bubbleList[j + 1], bubbleList[j]
        return bubbleList

    #测试
    if __name__ == '__main__':
        Numbers = [10, 8, 6, 7, 3, 5, 4, 1, 2, 0, 9]
        newNumbers = bSort(Numbers)
        for num in newNumbers:
            print("%d " % num, end='')

运行的效果:

Running D:/workspace_python/hello/bSort.py
0 1 2 3 4 5 6 7 8 9 10 

小结:

对于上两篇中写到的分别用PHP和java实现冒泡排序的算法来看,使用python来写确实是另外一种感觉,python在控制程序块的时候不再使用{},确实很特别。当然配合好用的IDE更加能够帮助提高效率,本次使用的是PyCharm

最近学习了一下javase的基础知识,有了一点点的概念,今天就趁着还有一点印象,赶紧练习一下。跟上一篇一样,小程序也是实现一个冒泡排序。

package com.luoanman.test;

public class bSortClass {
    /**
     * 排序
     *
     * @param Numbers
     * @return
     */
    public static int[] bSort(int[] Numbers) {
        int tmp;
        for (int i = 0; i < Numbers.length; i++) {
            for (int j = 0; j < Numbers.length - i - 1; j++) {
                if (Numbers[j] > Numbers[j +1]){
                    tmp = Numbers[j];
                    Numbers[j] = Numbers[j +1];
                    Numbers[j +1] = tmp;
                }

            }
        }
        return Numbers;
    }

    /**
     * 打印
     * @param Numbers
     */
    public static void printNums(int[] Numbers) {
        for (int num : Numbers) {
            System.out.format("%d ", num);
        }
        return;
    }

    public static void main(String args[]){
        int[] Numbers  = {10, 8, 6, 7, 3, 5, 4, 1, 2, 0, 9};
        printNums(bSort(Numbers));
    }
}

运行的结果实现了10个数字从小到大排序的效果

0 1 2 3 4 5 6 7 8 9 10 

在练习的过程中,遇到swap方法的问题,由于java在处理int类型的参数传递时是值传递的方式,无法通过swap方法内部的交换来影响方法外部的值,因此不能够像在PHP里那样写一个简单的swap方法实现值的交换。

应该说是出于工作的原因,原本常用的PHP的开发不再能够应付平时的任务需要,因此专门去学习了一些java以及python的基础知识,与此同时,将电脑上的开发环境也整理了一下,比如,将之前使用的NetBeans和eclipse更换掉,重新安装了PHPstorm和idea用于PHP和java的编程练习,在软件注册上面,用到了之前保留的大学邮箱,在试用之后,认为PHPstorm的确要更加方便。用于练习,接下来会分别试用PHP、java以及python来编冒泡排序的小程序。

PHP版的代码如下:

<?php
/**
 * Created by PhpStorm.
 * User: luoam
 * Date: 2018/4/14
 * Time: 22:46
 */
class bSortClass
{
    /**
     * 互换两个值
     * @param $a
     * @param $b
     */
    function swap(&$a, &$b)
    {
        if ($a > $b) {
            $tmp = $a;
            $a = $b;
            $b = $tmp;
        }
    }

    /**
     * 排序
     * @param $numbers
     * @return mixed
     */
    function bSort($numbers)
    {
        $num = count($numbers);
        for ($i = 0; $i < $num; $i++) {
            for ($j = 0; $j < $num - $i - 1; $j++) {
                $this->swap($numbers[$j], $numbers[$j + 1]);
            }

        }
        return $numbers;
    }

    /**打印数组
     * @param $nums
     */
    function printNums($nums)
    {
        foreach ($nums as $num) {
            printf("%s ", $num);
        }
    }
}

$bS = new bSortClass();
$nums = array(10,5,9,7,8,6,4,3,2,1,0);
$newNums = $bS->bSort($nums);
$bS->printNums($newNums);

运行结果如下:

D:\php-7.2.4\php.exe D:\workspace_php\test\test.php
0 1 2 3 4 5 6 7 8 9 10 
Process finished with exit code 0

顺便说一下,PHPstorm在配置了PHP的解释程序之后,可以在IDE界面运行PHP的脚本,这样不用专门去打开一些运行的窗口。