Python 入门

1、Python 环境准备

官网:https://www.python.org/ 

windows 资源: https://www.python.org/ftp/python/3.6.4/python-3.6.4-amd64.exe

python3

2314d8ad-0cff-490b-b570-e965ee77d0c0-366614.jpg

安装步骤

在默认地址安装 并 添加环境变量

4bf82e8a-b647-4c1a-95fe-6ad80ed6e535-366614.jpg

测试

cmd python

12cdfa9e-bc90-458a-bca0-b254c9052e3f-366614.jpg

IDE 工具:

PyCharm

安装

faf0e3f3-7808-4e76-85ba-308271835609-366614.jpg

创建项目

81f4314b-d104-4d39-aaba-1130debece71-366614.jpg

2、网页构造

基本网页结构

查看网页源代码 HTML CSS JavaScript

889a7f73-0a30-49c6-bf55-dec1b3cd2ae4-366614.jpg

自己写一个网页源码

head body div ul li img h p

引入CSS样式

9bb09e74-5719-4521-b762-5dbe2836e753-366614.jpg

3、网页解析

读取本地的 html 页面

先 open 获取文件 在read读取内容

转为字符串输出

c5f56b9c-823d-47a3-b886-b2951625187a-366614.jpg

解析字符串中的xpath路径

1. 安装第三方库 requests 和 lxml

d3cce850-5b82-45b3-8b17-bbcea6c11168-366614.jpg

 

2. 导入并使用  from lxml import etree

38e0ff45-d70a-411e-a175-2edf2a761b4a-366614.jpg

 

3. .xpath 解析字符路径 为节点

循环获取图片地址

a6c92beb-c09f-47b4-b481-75d5eb6b04f6-366614.jpg

4、真实网页请求(链家二手房信息)

通过 request 请求网络地址

get请求 输出获取到的文本

ef3af8b9-54f1-4117-ba29-e703c8da4824-366614.jpg

使用 xpath 解析

XPath定位 根据Class属性 找到对应的ul>li

fd0376eb-477c-4aa3-a8e9-26eb88edf755-366614.jpg

循环获取所有需要的数据

urls = ["https://cd.lianjia.com/ershoufang/pg{}/".format(str(i))for i in range(1,12)]

5ca2a318-5b18-4164-b722-c0adc4205b51-366614.jpg

5、Excel存储

使用 xlwt 库文件

Demo

dff75d28-90ee-41ae-99b5-da1e47446574-366614.jpg

案例代码

执行代码

a4b91902-5d08-4357-8374-8b4b2bde0aff-366614.jpg

结果

bf234591-c8b6-4ebe-9151-7e05f2a4f05c-366614.jpg

 

6、项目实战(微博数据)

浏览器调整到手机调试模式 方便获取数据

模拟登录:

随便一个页面的请求头中,拷贝cookie 和 用户代理信息

7742138c-ac12-4ee5-9049-0d14b3ff5804-366614.jpg

数据来源

Ajax 异步请求

542a1e97-c518-468b-89d9-0a7187a615fb-366614.jpg

基本用户信息的获取

使用 requests 请求库

用准备好的 cookie 通过 get 请求访问接口

b78e61d5-2bca-472c-8512-474ef7d429dd-366614.jpg

解析数据

json 库解析数据

把 json 字符串 转换为对象,获取对象的属性值

a76943cf-3c90-483f-8e00-74f02a1a1d26-366614.jpg

获取更多详细的信息

用户的详细信息

跟踪 user 的 uid,获取 containerid 和接口地址

94845eb5-7d81-4a58-a5ae-5e7cc649093d-366614.jpg

实例代码

获取根据 ui 获取到 对应用户的Json数据

api 地址通过 Chrome 浏览器复制

947d4a28-0630-4888-9be8-82ec72150aea-366614.jpg

正则表达式解析

通过 item_name 获取 key ; item_content 获取 Value

1 .在多行模式下不能匹配空格用\w\W代替;

2 ?非贪婪获取更多的字段 

3 * 任意多次 +至少一次 

测试

010f9cb6-b327-464c-87cf-b4791b8e4c95-366614.jpg

实例代码

python 正则查找方法 re.findall

10b244f0-27ce-41cf-9e84-b23da0c1f05f-366614.jpg

保存到数据库

MySQL 数据库 — 使用 pymyql 库

9d9b481b-077f-4a1c-ad5d-c65ff19f7dd4-366614.jpg

原文地址: http://www.52xjava.cn/2018/02/10/python-start/

后期更多猛料放出,关注 阿凯不错 公众号关注实时动态:

1526201714541657.jpg

Java 中的闭包 Closure

我们常常将数据、代码保存起来,以后再使用。但代码指令执行时候,会处于一定的环境,单纯将代码保存下来,还是不够的,需要将代码所处的环境也保存下来。

闭包其实是,将代码跟代码所处于的环境做为一个整体来看待,把相关参数和变量都保存在一起,从一个函数传递到另一个函数,以后再调用

这个概念和 对象(Objects)、代码块(block)、匿名函数(lambda)是相通的。

我们先从普通的函数来看:

1. 组合子(Combinator)
普通我们常说的一个“函数”:
f(x,y)=x+y
函数有两个“自变量”(术语:约束变量),x和y。函数的返回值,也就是应变量,是自变量一系列操作的结果。比如例子里是返回x和y的和。这样的一个它内部操作依赖的变量全部由参数提供了的”自给自足“的函数,叫“组合子(Combinator)”。

blob.png

Java代码表示就是:

public int add(int x, int y){
    return x+y;}

换到编程的概念,强调的就是函数的**“作用域”**。大多数编程语言都是用一对花括号**"{}"**标识出作用域。上面代码里的add()函数被调用之后,
int sum=add(2,3);
编译器编译之后,可以理解成是这个样子,函数的参数x和y,是包含在函数add()的作用域里的。

add(){
    int x=2;
    int y=3;
    return x+y;
}

或者,函数像下面这样写也可以。这时候x作为函数参数出现,而y作为函数局部变量出现。效果和上面的例子是一样的。

public int add(int x){
    int y=3;
    return x+y;
}

2. 自由变量
但有的时候,函数也可以有它自身作用域以外的参数参与。这些在函数作用域以外,由函数的外部环境提供的参数就叫“自由变量(Free Variable)”。

简单但不严格的说,一个函数的“自由变量”就是既不是参数也不是局部变量的变量。

比如下面这个x 的函数,返回xy 的和。这里的y就是自由变量。

f(x)=x+y
写成代码就是这样,

int y=3;
add(){
    int x=2;
    return x+y;
}

blob.png

一个纯粹(无副作用)的函数如果不含有自由变量,那么每次用相同的参数调用后的得到的结果肯定是一样的。

但如果一个函数含有自由变量,那么调用返回的结果不但依赖于参数的值,还依赖于自由变量的值。

因此一个含有自由变量的函数要正确执行,必须保证其所依赖的外围环境的存在。

3. 闭包(Closure)
大白话不怎么严谨的说法就是三点:

  1. 一个依赖于自由变量的函数
  2. 处在含有这些自由变量的一个外围环境
  3. 这个函数能够访问外围环境里的自由变量

看下面这个Javascript闭包的例子:

function Add(y) {  
    return function(x) {  
        return x + y  
    }  
} 

对内部函数function(x)来讲,y就是自由变量,而且function(x)的返回值,依赖于这个外部自由变量y。而往上推一层,外围Add(y)函数正好就是那个包含自由变量y的环境。而且Javascript的语法允许内部函数function(x)访问外部函数Add(y)的局部变量。满足这三个条件,所以这个时候,外部函数Add(y)对内部函数function(x)构成了闭包。

闭包的结构,如果用λ演算表达式来写,就是多参数的Currying技术。
> λx.λy.x+y

但在Java中我们看不到这样的结构。因为Java主流语法不允许这样的直接的函数套嵌和跨域访问变量。

4. 类和对象
但Java中真的不存在闭包吗?正好相反,Java到处都是闭包,所以反而我们感觉不出来在使用闭包。因为Java的“对象”其实就是一个闭包。其实无论是闭包也好,对象也好,都是一种数据封装的手段。看下面这个类,

class Add{
    private int x=2;
    public int add(){
	int y=3;
    	return x+y;
    }
}

看上去x在函数add()的作用域外面,但是通过Add类实例化的过程,变量”x“和数值”2“之间已经绑定了,而且和函数add()也已经打包在一起。add()函数其实是透过this关键字来访问对象的成员字段的。

5. 内部类是闭包:包含指向外部类的指针
Java中的内部类就是一个典型的闭包结构。代码如下

public class Outer {
    private class Inner{
        private x=100;
        public int innerAdd(){
            return x+y;
        }
    }
    private int y=100;
}

下图画的就是上面代码的结构。内部类(Inner Class)通过包含一个指向外部类的引用,做到自由访问外部环境类的所有字段,变相把环境中的自由变量封装到函数里,形成一个闭包。

blob.png

6、别扭的匿名内部类

但Java匿名内部类就做得比较尴尬。下面这个例子中,getAnnoInner负责返回一个匿名内部类的引用。

interface AnnoInner(){addXYZ();}
public
class Outer {    public AnnoInner getAnnoInner(final int x){        final int y=100;        return new AnnoInner(){            int z=100;            public int addXYZ(){return x+y+z;}
           //这个函数无法修改外部环境中的自由变量y。
           //public void changeY(){y+=1;}
       };    }    private int num=100;}

匿名内部类因为是匿名,所以不能显式地声明构造函数,也不能往构造函数里传参数。不但返回的只是个叫AnnoInner的接口,而且还没有和它外围环境getAnnoInner()方法的局部变量x和y构成任何类的结构。但它的addXYZ()函数却直接使用了x和y这两个自由变量来计算结果。这就说明,外部方法getAnnoInner()事实上已经对内部类AnnoInner构成了一个闭包。

但这里别扭的地方是这两个x和y都必须用final修饰,不可以修改。如果用一个changeY()函数试图修改外部getAnnoInner()函数的成员变量y,编译器通不过,

error: cannot assign a value to final variable y

这是为什么呢?因为这里Java编译器支持了闭包,但支持地不完整。说支持了闭包,是因为编译器编译的时候其实悄悄对函数做了手脚,偷偷把外部环境方法的x和y局部变量,拷贝了一份到匿名内部类里。如下面的代码所示。

interface AnnoInner(){addXYZ();}
public class Outer {    public AnnoInner getAnnoInner(final int x){        final int y=100;        return new AnnoInner(){
          //编译器相当于拷贝了外部自由变量x的一个副本到匿名内部类里。
          int copyX=x;
          //编译器相当于拷贝了外部自由变量y的一个副本到匿名内部类里。
   int copyY=y;            int z=100;

          //这个函数无法修改外部环境中的自由变量y。
          //public void changeY(){y+=1;}

           public int addXYZ(){return x+y+z;}                    };    }    private int num=100;}

所以用R大回答里的原话说就是:

Java编译器实现的只是capture-by-value,并没有实现capture-by-reference。

而只有后者才能保持匿名内部类和外部环境局部变量保持同步。

但Java又不肯明说,只能粗暴地一刀切,就说既然内外不能同步,那就不许大家改外围的局部变量。

7. 其他和匿名内部类相似的结构
《Think in Java》书里,只点出了匿名内部类来自外部闭包环境的自由变量必须是final的。但实际上,其他几种不太常用的内部类形式,也都有这个特性。

比如在外部类成员方法内部的内部类。

public class Outer {
    public foo(final int x){
        final int y=100;
        public class MethodInner{
	    int z=100;
            public int addXYZ(){return x+y+z;}
        }
    }}

比如在一个代码块block里的内部类。

public class Outer {
    {
        final int x=100;
        final int y=100;
        class BlockInner{
            int z=100;
            public int addXYZ(){return x+y+z;}
        }
        BlockInner bi=new BlockInner();
        num=bi.addXYZ();
    }
	private int num;}