Sylvia's blog


  • Home

  • Archives

  • Tags

BullseyeCoverage覆盖率统计

Posted on 2018-09-29

BullseyeCoverage(以下称ccvoer)是由Bullseye提供的C/C++代码覆盖率测试工具,可统计:函数、分支、类覆盖率,可用于单测,自动化测试等测试阶段的覆盖率统计工作中,是一种有效的发现未被测试覆盖的代码的手段

原理

ccover采用的是先对代码进行插桩,然后收集覆盖数据,最后分析覆盖率原理的技术。
其工作原理是:
编译插桩:针对不同的编译器,设计一个和真实编译器名字相同的拦截器,这些拦截器文件存放在 ccover的bin目录下。当覆盖编译开关打开时,文件在编译过程中将首先被这些拦截器所拦截,而不是由真实的编译器去编译源代码。在这个拦截过程中,拦截器将一系列探针代码插入到C/C++源代码中,即插桩过程,然后带有桩代码的文件再次通过真实的编译器生成可执行二进制文件和覆盖分析文件(test.cov),此时的二进制文件具备被ccover分析的条件,而插桩信息被记录在test.cov中。在当覆盖编译开关关闭时,这些拦截器将直接调用真实的编译器而不进行代码插桩的过程。
收集覆盖数据:运行测例过程中,被插桩后的二进制文件在执行时会将覆盖率信息写入test.cov。
分析覆盖率:采用covsrc等命令基于test.cov获取覆盖率统计数据。

使用步骤

  1. 下载源码并安装ccover
  2. 声明ccover和使用的编译器路径
  3. 开启覆盖率编译开关
    cov01 -1
  4. 声明覆盖分析文件的输出路径和名称,一般为test.cov
  5. 获取被测试代码,编译
  6. 关闭覆盖率编译开关
    cov01 -0
  7. 将编译后的可执行文件和输出的test.cov复制到测试代码目录下
  8. 声明覆盖数据写入文件路径(复制后的test.cov)
  9. 执行测试代码,覆盖率信息写入test.cov(如果不复制test.cov,会提示生成和使用的test.cov为同一文件)
  10. 基于test.cov文件统计覆盖率

ccover命令

covdir 查看文件夹覆盖率
covsrc
查看文件覆盖率
covfn
查看函数覆盖率
covclass
查看类覆盖率
covbr
查看分支覆盖率

covselect
文件过滤

–> 没有被执行到的函数、条件判断、switch、while/for、catch等
X 某个函数已被执行,并支持classs内的函数
T/t 某处条件判断为真
F/f 某处条件判断为假
TF/tf 某处条件判断时,真假值都成立过
K 某处条件为常量

facets介绍

Posted on 2018-09-11

facets是谷歌的开源数据可视化工具,可以从均值、缺失值以及分布形态等多方面对特征列进行分析和可视化展示,有利于初步掌握数据的分布和趋势。就像官网说的,,数据的清洗和过滤对模型起着至关重要的作用,通过facets对样本数据进行分析,可以尽早发现数据问题,例如缺失值过多,数据分布不均匀等,可以说是数据分析的第一步。
facets可以作为pandas库的辅助可视化工具,相信会事半功倍。
官网
github
(知乎)介绍

golang操作数据库

Posted on 2018-08-27

go官方提供了database package,包含sql和sql/driver两个包,定义了操作数据库的接口。
而连接数据库的driver需要依赖第三方包

数据包

1
2
3
4
import (
"database/sql"
_ "github.com/go-sql-driver/mysql"
)

数据库的连接与关闭

sql.Open()不建立与数据库的任何连接,也不会验证驱动连接参数。相反,它只是准备数据库抽象以供以后使用.
函数原型如下,返回一个sql.DB指针
func Open(driverName, dataSourceName string) (*DB, error)

  • driverName: 使用的驱动名. 这个名字其实就是数据库驱动注册到 database/sql 时所使用的名字.
  • dataSourceName: 数据库连接信息,这个连接包含了数据库的用户名, 密码, 数据库主机以及需要连接的数据库名等信息.
    1
    2
    3
    4
    5
    6
    7
    8
    func main() {
    db, err := sql.Open("mysql",
    "user:password@tcp(127.0.0.1:3306)/hello")
    if err != nil {
    log.Fatal(err)
    }
    defer db.Close()
    }

当真正进行第一次数据库查询操作时, 此时才会真正建立网络连接

sql.DB的设计就是用来作为长连接使用的。不要频繁Open, Close。比较好的做法是,为每个不同的datastore建一个DB对象,保持这些对象Open。如果需要短连接,那么把DB作为参数传入function,而不要在function中Open和Close

数据库操作

Prepare()

预编译语句,返回一个Stmt,Stmt对象可以执行Exec()、Query()、QueryRow()等操作
使用该方法的优势有

  • 可以实现自定义参数的查询
  • 比手动拼接字符串 SQL 语句高效
  • 可以防止SQL注入攻击
    自定义参数的占位符为:在MySql中,参数占位符为?;PostgreSql中为$N,其中N为数字;SQLite接受这两者之一;在Oracle中占位符以冒号开始,并命名为:param1

Exec()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
stmt, err := db.Prepare("INSERT INTO users(name) VALUES(?)")
if err != nil {
log.Fatal(err)
}
res, err := stmt.Exec("Dolly")
if err != nil {
log.Fatal(err)
}
lastId, err := res.LastInsertId()
if err != nil {
log.Fatal(err)
}
rowCnt, err := res.RowsAffected()
if err != nil {
log.Fatal(err)
}
log.Printf("ID = %d, affected = %d\n", lastId, rowCnt)

Query()

执行 SQL 语句

1
2
3
4
5
6
7
8
9
db, err := sql.Open("mysql", "jesse:jesse@tcp(127.0.0.1:3306)/?charset=utf8") 
checkErr(err)
db.Query("drop database if exists tmpdb")
db.Query("create database tmpdb")
db.Query("use tmpdb")
db.Query("create table tmpdb.tmptab(c1 int, c2 varchar(20), c3 varchar(20))")
db.Query("insert into tmpdb.tmptab values(101, '姓名1', 'address1'), (102, '姓名2', 'address2'), (103, '姓名3', 'address3'), (104, '姓名4', 'address4')")
db.Query("delete from tmpdb.tmptab where c1 = 101")
db.Close()

对查询操作

  1. 调用 db.Query 执行 SQL 语句,返回一个 Rows 作为查询的结果
  2. 通过 rows.Next() 迭代查询数据
  3. 通过 rows.Scan() 读取查询到每一行数据
  4. 调用 db.Close() 关闭查询
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    var (
    id int
    name string
    )
    rows, err := db.Query("select id, name from users where id = ?", 1)
    if err != nil {
    log.Fatal(err)
    }
    defer rows.Close()
    for rows.Next() {
    err := rows.Scan(&id, &name)
    if err != nil {
    log.Fatal(err)
    }
    log.Println(id, name)
    }
    err = rows.Err()
    if err != nil {
    log.Fatal(err)
    }

用defer内置函数推迟了rows.Close()的执行
每次db.Query操作后, 都建议调用rows.Close(). 因为 db.Query() 会从数据库连接池中获取一个连接, 这个底层连接在结果集(rows)未关闭前会被标记为处于繁忙状态。当遍历读到最后一条记录时,会发生一个内部EOF错误,自动调用rows.Close(),但如果提前退出循环,rows不会关闭,连接不会回到连接池中,连接也不会关闭, 则此连接会一直被占用. 因此通常我们使用 defer rows.Close() 来确保数据库连接可以正确放回到连接池中

QueryRow()

单行查询

1
2
3
4
5
6
var name string
err = db.QueryRow("select name from users where id = ?", 1).Scan(&name)
if err != nil {
log.Fatal(err)
}
fmt.Println(name)

与Prepare()一起使用

1
2
3
4
5
6
7
8
9
10
stmt, err := db.Prepare("select name from users where id = ?")
if err != nil {
log.Fatal(err)
}
var name string
err = stmt.QueryRow(1).Scan(&name)
if err != nil {
log.Fatal(err)
}
fmt.Println(name)

Nginx使用

Posted on 2018-08-20

反向代理

当客户端发来HTTP请求时,Nginx不会立刻转发到上有服务器,而是把请求完整的接收后,再向上有服务器发起连接,把缓存的客户端请求转发到上游服务器。

​ 这种反向代理的方式,缺点是延长了一个请求的时间、增加了缓存;优点则是减轻了上游服务器的压力,因为外部请求的传输速度相对于内部转发较慢,缓存完外部请求后再请求上游服务器可以减少维持连接的时间,进而减轻了上游服务器的压力。

/webserver/nginx/conf/nginx.conf示例配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
user  nobody;
worker_processes 1;
error_log logs/error.log info;

events {
worker_connections 1024;
}

http {
server {
listen 80;
server_name www.linuxidc.com;
access_log logs/linuxidc.access.log main;
location / {
index index.html;
root /var/www/linuxidc.com/htdocs;
}
}

server {
listen 80;
server_name www.Androidj.com;
access_log logs/androidj.access.log main;
location / {
index index.html;
root /var/www/androidj.com/htdocs;
}
}
}

mail {
auth_http 127.0.0.1:80/auth.php;
pop3_capabilities "TOP" "USER";
imap_capabilities "IMAP4rev1" "UIDPLUS";

server {
listen 110;
protocol pop3;
proxy on;
}
server {
listen 25;
protocol smtp;
proxy on;
smtp_auth login plain;
xclient off;
}
}

存在于 main 上下文中的配置指令如下:
user
worker_processes
error_log
events
http
mail

存在于 http 上下文中的指令如下:
server

存在于 mail 上下文中的指令如下:
server
auth_http
imap_capabilities

存在于 server 上下文中的配置指令如下:
listen
server_name
access_log
location
protocol
proxy
smtp_auth
xclient

存在于 location 上下文中的指令如下:
index
root

usr/local/webserver/nginx/sbin/nginx # 启动Nginx
usr/local/webserver/nginx/sbin/nginx -s reload # 重新载入配置文件
usr/local/webserver/nginx/sbin/nginx -s reopen # 重启 Nginx
usr/local/webserver/nginx/sbin/nginx -s stop # 停止 Nginx

git使用

Posted on 2018-08-14

官网

命令

1. 基本操作

设置提交代码时的用户信息

1
2
git config [--global] user.name "[name]"`
git config [--global] user.email "[email address]"

–global参数,表示这台机器上所有的Git仓库都会使用这个配置。

创建新仓库

1
git init

创建ssh key
本地Git仓库和github仓库之间的传输通过ssh加密的,远程服务器端需要添加ssh 公钥
默认在用户主目录下,生成.ssh目录,包含id_rsa和id_rsa.pub两个文件。id_rsa是私钥,id_rsa.pub是公钥

1
ssh-keygen  -t rsa –C "email@example.com"

克隆仓库

1
2
本地:git clone /path/to/repository 
远程:git clone username@host:/path/to/repository

关联本地仓库与远程仓库

1
git remote add origin <server>

查看远程仓库信息

1
git remote -v

远程仓库的默认名称是origin

查看状态

1
git status

添加改动到暂存区

1
2
git add <filename1> <filename2>
git add .

“.”表示添加所有文件、文件夹和子文件夹
提交到仓库

1
git commit -m "代码提交信息"

推送本地改动到远程

1
git push origin master

下载远程改动到本地

1
git fetch

合并拉取的代码

1
git merge

拉取远程最新改动并与本地合并

1
git pull

图形化查看提交与改动

1
gitk --all

2. 分支

假设准备开发新功能,需要两周才能完成,如果立刻提交,代码没写完的情况下,不完整的代码库会导致其他人无法继续开发;而等代码全部写完再一次提交,又存在丢失每天进度的巨大风险。
创建属于自己的分支,想提交就提交,直到开发完毕后,再一次性合并到原来的分支上,这样,既安全,又不影响别人工作。
鼓励使用分支完成某个任务,合并后再删掉分支
创建分支

1
git branch feature_x

本地新建的分支如果不推送到远程,对其他人就是不可见的

切换分支

1
git checkout master

创建并切换

1
git checkout -b feature_x

查看当前分支

1
git branch

合并分支到当前分支
合并分支时,Git会优先用Fast forward模式,但这种模式下,删除分支后,会丢掉分支信息。
如果要强制禁用Fast forward模式,Git就会在merge时生成一个新的commit,这样,从分支历史上就可以看出分支信息

1
2
git merge <branch>
git merge --no-ff -m "merge with no-ff" <branch>

删除分支

1
git branch -d feature_x

-D : 强行删除没有被合并过的分支
删除远程分支

1
2
git push origin --delete [branch-name]
git branch -dr [remote/branch]

推送分支到远程仓库

1
git push origin <branch>

查看文件、分支差异
git diff命令,不指定filename时,列出所有文件

1
2
3
4
5
6
7
git diff <filename>						工作区和暂存区
git diff <branch_1> <branch_2> 两个分支
git diff --cached <filename> 暂存区和版本库最新版本
git diff --cached <commit> <filename> 暂存区和版本库指定版本
git diff <commit> <filename> 工作区和版本库指定版本
git diff HEAD -- <filename> 工作区和版本库里面最新版本(commit=HEAD)
git diff <commit> <commit> 版本库两个版本

其中<commit>支持下列方式:
HEAD 最经一次commit
HEAD^ 上一次提交
HEAD~100 上100次提交
版本号
列出分支

1
2
3
本地:git branch
远程:git branch -r
所有:git branch -a

3. 撤销修改与版本回退

查看提交历史

1
2
git log
git log --stat

用以回退
查看命令历史

1
git reflog

可以去未来
撤销工作区改动

1
git checkout -- <filename>

会使用 HEAD 中的最新内容替换掉你的工作目录中的文件。已添加到缓存区的改动,以及新文件,都不受影响。即回到最近一次git commit或git add时的状态

撤销暂存区修改

1
git reset HEAD <filename>

把暂存区的修改撤销掉(unstage),重新放回工作区

版本回退

1
2
3
git reset --hard HEAD^
git reset --hard HEAD^^
git reset --hard HEAD~100

3. 工作现场

隐藏工作现场

1
git stash

查看被隐藏的工作现场

1
git stash list

恢复工作现场

1
2
git stash apply
git stash pop 同时删除stash

删除stash

1
git stash drop

4. 标签

创建标签在当前commit

1
git tag 1.0.0 版本号

列出所有tag

1
git tag

删除本地tag

1
git tag -d <tagname>

创建的标签都只存储在本地,不会自动推送到远程。所以,打错的标签可以在本地安全删除

推送标签到远程

1
2
git push origin <tagname>			推送一个本地标签
git push origin --tags 推送全部未推送过的本地标签

删除远程标签
先从本地删除,然后,从远程删除

1
2
git tag -d v0.9
git push origin :refs/tags/v0.9

5. 自定义Git

设置命令颜色显示

1
git config --global color.ui true

设置别名

1
git config --global alias.st status

场景

  1. 想要丢弃你所有的本地改动与提交,与远程最新改动保持一致
    可以到服务器上获取最新的版本并将你本地主分支指向到它:

    1
    2
    git fetch origin
    git reset --hard origin/master
  2. 已经在本地创建Git仓库,想在github创建相同的Git仓库,保证两个仓库远程同步(备份或远程协作)
    可以在远程创建空仓库,关联本地仓库与远程仓库,推送本地到远程

    1
    2
    git remote add origin <server>
    git push -u origin master
  3. 同一台服务器创建多个ssh key
    场景:有多个用户使用同一台服务器,均需要在服务器上拉取远程代码,因此服务器需要校验多个用户的ssh
    操作步骤:
    创建非全局用户A
    git config user.name "A"
    git config user.email "A@hotmail.com"
    生成A用户的ssh
    ssh-keygen -t rsa -C “A@hotmail.com”
    默认生成的文件名是id_rsa和id_rsa.pub,为方便其他用户生成属于自己的ssh,而A用户的不会被覆盖,生成的文件最好改名(例A_id_rsa, A_id_rsa.pub)
    为保证多个ssh可共同起作用,在.ssh文件下,新建config文件,配置多用户,文件格式为

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    #github Aemail@gmail.com
    host github.com #别名,随便定 后面配置地址有用
    Hostname github.com #要连接的服务器
    User A #用户名
    IdentityFile ~/.ssh/A_id_rsa #密钥文件的地址,注意是私钥

    #github Bemail@gmail.com
    host github.com
    Hostname github.com
    User B
    IdentityFile ~/.ssh/B_id_rsa
  4. ignore
    ignore可以设置提交时忽略的文件。
    如果想某被忽略文件提交,可以用-f参数强制提交
    如果某文件被忽略,但并不是本意,可能是规则写错了,可以用git check-ignore命令检查哪个规则写错

  5. 多人协作分支开发
    a. 当克隆远程仓库时,只能克隆master分支,假定需要多人同时在dev上开发,每个参与开发的人都需要在本地创建和远程分支对应的分支git checkout -b branch-name origin/branch-name
    b. 尝试用git push origin <branch-name>推送自己的修改;
    c. 如果推送失败,则因为远程分支比你的本地更新,需要先用git pull试图合并,提示no tracking information,则说明本地分支和远程分支的链接关系没有创建,用命令git branch --set-upstream-to <branch-name> origin/<branch-name>;
    d. 如果合并有冲突,则解决冲突,并在本地提交;
    f. 没有冲突或者解决掉冲突后,重新推送

  6. 对不同仓库指定不同的用户名和Email地址
    场景:同一个用户在电脑上需要从两个不同的git服务平台拉取,改动和提交代码,而这两个平台的用户名和密码都不同(例如,在电脑上想要同时push公司和github个人账号的代码)
    操作步骤:
    两个平台的账号可以视为两个用户,假设公司账号为A用户,github账号为B用户,即参照场景3可生成用户A和用户B的ssh,并配置config文件如下

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    #公司 A@company.com
    host companyalias #别名,随便定 后面配置地址有用
    Hostname company.com #要连接的服务器
    User A #用户名
    IdentityFile ~/.ssh/A_id_rsa #密钥文件的地址,注意是私钥

    #github B@gmail.com
    host githubalias
    Hostname github.com
    User B
    IdentityFile ~/.ssh/B_id_rsa

    使用ssh的ssh-add命令将密钥添加到 ssh-agent 的高速缓存中,这样在当前会话中就不需要再次输入密码了
    ssh-agent bash
    //A账户的私钥
    ssh-add ~/.ssh/A_id_rsa
    //B账户的私钥
    ssh-add ~/.ssh/B_id_rsa
    //查看密钥列表
    ssh-add
    通过更改每个项目的.git文件夹的config文件,来定义该项目push的远程地址

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    [core]
    repositoryformatversion = 0
    filemode = true
    bare = false
    logallrefupdates = true
    ignorecase = true
    precomposeunicode = true
    [user]
    email = A@github.com
    name = lapisy
    [remote "origin"]
    url = git@github.com:remoteurl/RecyclerViewSample.git
    fetch = +refs/heads/*:refs/remotes/origin/*
    [branch "master"]
    remote = origin
    merge = refs/heads/master

    push时可能会碰到如下问题:

    1
    2
    3
    4
    5
    6
    remote: error: GH007: Your push would publish a private email address.
    remote: You can make your email public or disable this protection by visiting:
    remote: http://github.com/settings/emails
    To lapisy:Lapisy/RecyclerViewSample.git
    ! [remote rejected] master -> master (push declined due to email privacy restrictions)
    error: failed to push some refs to 'git@githubalias:remoteurl/RecyclerViewSample.git'

    url = git@github.com:remoteurl/RecyclerViewSample.git需要修改为
    url = git@githubalias:remoteurl/RecyclerViewSample.git
    config文件

    解决方法:登录github,settings–>emails,不勾选keep my email address private或者勾选block command line pushes that expose my email

  7. 开发新功能过程中(未开发完)需要修bug
    隐藏当前工作现场,此时查看工作区是干净的
    git stash
    确定要在哪个分支上修复bug,假定需要在master分支上修复,就从master创建临时分支
    git checkout master
    git checkout -b issue-101
    修复bug,提交,切换到master分支,并完成合并,最后删除issue-101分支
    git add readme.txt
    git commit -m "fix bug 101"
    git checkout master
    git merge --no-ff -m "merged bug fix 101" issue-101
    回到dev分支继续开发
    git checkout dev

leetcode--mysql

Posted on 2018-07-27

leetcode – Database题目

595. Big Countries

where
and, or, between
like
in
not

1
2
3
select name, population, area
from World
where area > 3000000 or population > 25000000;

627. Swap Salary

620. Not Boring Movies

182. Duplicate Emails

1
2
3
Select distinct a.Email
from Person a, Person b
where a.Email = b.Email and a.Id != b.Id

175. Combine Two Tables

1
2
3
select p.FirstName, p.LastName, a.City, a.State
from Person p left join Address a
on p.PersonId=a.PersonId;

181. Employees Earning More Than Their Managers

1
2
3
select a.Name
from Employee a, Employee b
where a.Salary > b.Salary and a.ManagerId = b.Id

183. Customers Who Never Order

1
2
3
select Customers.Name as Customers
from Customers
where Customers.Id not in (select CustomerId from Orders)

596. Classes More Than 5 Students
197. Rising Temperature
196. Delete Duplicate Emails
176. Second Highest Salary

select ifnull(exp1, exp2)
exp1 is not null return corresponding field, else return exp2

distinct
返回唯一值

desc, asce
只对跟着的字段有效

1
2
3
4
select ifnull(
(select Salary from Employee order by Salary desc limit 1,1),
null)
as SecondHighestSalary;

key :
注意返回的字段是否命名
当有重复数据

medium
626. Exchange Seats
178. Rank Scores

1
2
3
select Score, (select count(distinct a.Score) from Scores a where a.Score >= b.Score) as Rank
from Scores b
order by Score desc

180. Consecutive Numbers

1
2
3
select distinct L2.Num as ConsecutiveNums
from Logs L1, Logs L2, Logs L3
where L1.Id = L2.Id-1 and L3.Id = L2.Id+1 and L1.Num = L2.Num and L3.Num = L2.Num

184. Department Highest Salary
177. Nth Highest Salary

1
2
3
4
5
6
7
8
CREATE FUNCTION getNthHighestSalary(N INT) RETURNS INT
BEGIN
declare m int;
set m = N-1;
RETURN (
select distinct Salary from Employee order by Salary desc limit m, 1
);
END

hard
601. Human Traffic of Stadium
185. Department Top Three Salaries
262. Trips and Users

curl命令

Posted on 2018-07-06

利用url规则在命令行下工作的文件传输工具

简言之,在linux命令行模式下,可以达到访问网页,下载网页中文件的功能。
可以设置代理、cookies等,网页以html形式显示。

1. 语法

curl [option] [url]

2. 参数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
-H/--header							 设置header(每个header的设置用一个-H)
-A/--user-agent <string> 设置用户代理发送给服务器
-b/--cookie <name=string/file> cookie字符串或文件读取位置
-c/--cookie-jar <file> 操作结束后把cookie写入文件
-C/--continue-at <offset> 断点续转
-D/--dump-header <file> 把header信息写入文件
-e/--referer 来源网址
-f/--fail 连接失败时不显示http错误
-o/--output 把输出写入文件
-O/--remote-name 把输出写入文件,保留远程文件的文件名
-r/--range <range> 检索来自HTTP/1.1或FTP服务器字节范围
-s/--silent 不输出任何东西
-T/--upload-file <file> 上传文件
-u/--user <user[:password]> 设置服务器的用户和密码
-w/--write-out [format]
-x/--proxy <host[:port]> 在给定的端口上使用HTTP代理
-#/--progress-bar 进度条显示当前的传送状态

3. 用法示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
1. 访问网页,以html形式显示
curl http://www.baidu.com
2. 保存网页到文件
curl http://www.baidu.com >> baidu.html
curl -o baidu.html http://www.baidu.com
3. 下载网页z中的文件
curl -o b.jpg http://www.baidu.com/a.jpg
curl -O http://www.baidu.com/a.jpg
4. 测试网页返回值
curl -o /dev/null -s -w ${http_code} http://www.baidu.com
5. 指定代理服务器
curl -x 192.168.100.100:1080 http://www.baidu.com
6. 上传文件
7. 显示抓取错误
curl -f http://www.baidu.com
8. 设置header
curl -H 'Accept-Language:es' http://www.baidu.com
9. 发送get请求
curl http://localhost/test/adduser?id=100&name=test
10. 发送post请求
写在header
curl -d "id=100&name=test" http://localhost/test/adduser
body形式
curl -H "Accept: application/json" -H "Content-type: application/json" -X POST -d '{"id":100}' http://localhost/test/adduser

ElasticSearch简介

Posted on 2018-06-28

es是为提高搜索效率而存在的一种分布式引擎,它支持文档型数据,采用json形式保存,其中的概念和关系型数据库的对应关系为:

关系数据库 ⇒ 数据库(Database) ⇒ 表(Table) ⇒ 行(Row) ⇒ 列(Columns)
Elasticsearch ⇒ 索引(Index) ⇒ 类型(Type) ⇒ 文档(Document) ⇒ 字段(Fields)

关系型数据库采用树结构存储,因为二叉树的查找复杂度为logN,并且在插入时不用移动全部节点,可以同时兼顾查询和插入的性能

es采用倒排索引

多线程爬虫在linux下保存路径错误

Posted on 2018-06-22

日期

2018-6-22

问题

之前基于python写了一个多线程爬取图片的爬虫代码,爬取图片都保存在output文件夹里,输出目录不存在时会创建目录。代码在win10系统下执行正常,但在linux系统下,文件直接保存在了代码根目录,output为空

微信图片_20180622103003

1529634662211

原因

代码拼接根目录和数据目录时采用+"//"+,,liunx目录不支持双斜杠

修复

linux目录为单斜杠+"\"+,并且这种方式windows兼容

解决时间

安装linux双系统(2h),解决问题(5min)

教训

虽然用windows写的,应该考虑到linux的开发环境,使得自己的代码支持跨平台
以后目录拼接均用单斜杠

其他

1 爬取内容的保存
基于requests库发起请求并保存响应内容;或者直接用urllib.request.urlretrieve()将远程内容保存到本地
我采用了方法一,代码如下:(下图的content即是上图的html)1529635964157

1529637195810

1529634951191

2 爬虫保存图片形式

  • windows平台下必须以二进制形式保存,即open函数参数为’wb’,如果只是’w’参数,图片如下
    https___avatar.csdn.net_E_4_E_3_ababybear
  • linux中,忽略b参数,图片形式正常

3 linux文件的颜色与类型
绿色:可执行文件
蓝色:目录
红色:压缩包
白色:一般性文件,例文本文件,配置文件,源码文件
黄色:设备
浅蓝色:链接文件
灰色:其他

python常用库

Posted on 2018-06-21
  • web 框架:Django/Flask/Tornado
  • ORM: sqlalchemy, Peewee
  • 表单验证:WTForms
  • 数据处理和分析:Numpy, Pandas, Matplotlib
  • 异步:celery, asyncio, tornado
  • 并发:gevent, threading, concurrent.futures
  • 部署:uwsgi, gunicorn
  • html解析: lxml, beautifulsoup
  • 爬虫:requests, Scrapy
  • 单元测试:unittest, nose, pytest
  • 图片处理:pillow
  • python2/3 兼容:six, 2to3
  • 代码检测:autopep8, pylint, flake8, mypy(python3)
  • 调试:Ipython, Ipdb, pdbpp
12
Sylvia

Sylvia

一勺辣酱, 五味人生

17 posts
5 tags
© 2018 Sylvia
Powered by Hexo
Theme - NexT.Muse