python基础

python介绍

  • 解释型、面向对象的语言,1991正式公布
  • 特点:
    • 可读性强
    • 语法简洁(由C开发)
    • 面向对象
    • 免费和开源
    • 可移植性和跨平台
  • 应用范围:
    • 科学计算
    • 人工智能
    • web服务器端和大型网站后端
    • GUI开发(图形用户界面)
    • 游戏开发
    • 移动设备
    • 嵌入式设备
    • 系统运维
    • 大数据
    • 云计算
  • 缺点:
    • python解释型语言,性能低(解释器越来越快)
    • python2停止更新,[2,3]不兼容
  • 解释器
    • python程序执行依赖于解释器(主要是cpython)

python开发环境

  1. IDLE
  2. Pycharm
  3. wingIDE
  4. Eclipse
  5. Ipython

图形化程序设计

  • turtle模块语法 as t
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
49
50
51
52
53

"""画笔运动命令"""

t.left(degree) #向左转
t.right(degree) #向右转
t.pendown() #放下画笔
t.penup() #提起画笔
t.circle(半径,degree) #按多少半径和度数画圆,半径为负(正)圆心在画笔右边(左)
t.goto(x,y) #将画笔移动到哪个坐标
t.forward(distance) #向当前方向前进多少距离
t.backward(distance) #向当前方向相反前进多少距离
home() #设置当前画笔位置为原点,朝向东
seth(degree) #设置当前朝向度数


"""画笔控制命令"""
t.fillcolor('color') #绘制图形,填充颜色
t.color(color1,color2) #同时设置pencolor、fillcolor
t.filling() #返回是否处于填充状态
t.begin_fill() #开始填充图形
t.end_fill() #填充完成
t.hideturtle() #隐藏画笔turtle形状
t.showturtle() #显示画笔turtle形状
```
### python基本知识
1. python程序由模块组成,一个模块对应python源文件,对应后缀.py
2. 模块由语句组成,程序依次执行
3. 一般4空格缩进,不强制空格数
4. `\`行连接符,使代码更加美观
5. python中一切皆对象,`对象本质就是:一个内存块,拥有特定值,支持特定类型的相关操作`
- 车位表示内存,id(标识identity)表示车位编号,车位停的什么车类型(type),详细车牌号表示值(value)
- id()内存地址,type()类型,print()值
- 赋给变量(对象引用)的是内存地址(对象)
6. 引用
- 变量位于 : 栈内存
- 对象位于 : 堆内存(id,type,value)
7. 标识符: 用于变量、函数、类、模块等名称
8. 赋值
- `链式赋值`用于对同一个对象进行多变量赋值 x=y=12 --> x=12,y=12
- `系列解包赋值` a,b,c = 1,2,3 --> a=1,b=2,c=3 | a,b = b,a
- `常量`没有语法来限制改变常量值,可以改变
9. 循环性能优化
- 尽量减少循环内部不必要计算,往外层放
- 尽量使用局部变量查询较快
- 连接字符串使用join,不使用+(产生新的字符串对象)
- 列表操作(删除,插入)尽量在尾部,容易导致后面数据变动
10. zip()并行迭代
```python
names=['a','b','c']
ages=[1,2,3,4]
jobs=['好','事','情']
for i,k,j in zip(names,ages,jobs):
print('{0}--{1}--{2}'.format(i,j,k))
  1. 推导式
  • 列表推导式:
    [表达式 for item in 可迭代对象 if 条件判断]
    如: [x**2 for x in range(1,5) if x%5==0]
    #得到嵌套循环实现的(x,y)
    [(row,col) for row in range(3) for col in range(3)]
  • 字典推导式
    {c:mytest.count(c) for c in mytest} #统计每个字符的出现字数
  • 集合推导式
    相当于用花括号的列表
  • 生成器推导式(生成元组)
    (x**2 for x in range(1,5) if x%5==0) — <得到生成器对象,可迭代对象>
    #一个生成器只能运行一次,第一次遍历得到数据,第二次遍历没有数据了

markdown语法

书写格式Markdown

1、行间文字

  • 用法: 通常用一对`表示加上底色的行间文字
    • 实例: `底色行间文字`

2、标题制作

  • 用法: 文字左边添加#表示标题,且#的数量决定了标题的级别,最多可以表示六级
    • 实例: # 一级标题 ## 二级标题……######六级标题

3、改变字体

  • 用法: 粗体: 用一对**表示强调,显示粗体
    • 实例: **加粗内容**
  • 用法: 斜体: 用一对*表示斜体
    • 实例: *斜体内容*
  • 附加用法: ***斜体+加粗内容***

4、代码区设置

  • 用法1:
    ```什么语言(python、bash…)
    代码块
    ```
  • 行内代码块,不加语言类型,用法2:
    ```
    代码块
    ```
  • 用法3:
    • 行的开头空4个空格/一个tab,表示接下来的内容是程序代码
    • 注意事项:
      (1)在代码区块内部,”, <>,& 将会自动转换为转义字符
      (2)在代码区块内部,Markdown 不被解释为特殊标记,即:星号(*)就是星号(*),

5、格式工具

  • 换行、分段标记: 行尾敲两个空格,然后回车键
  • 分割标记: 三个以上的***或者---
  • 转义字符: \, 无需转义的 < 和 &

6、删除文字

  • 用法: ~~删除文字~~

7、无序列表

- 内容(+、-、*效果相同)
空格- 子内容1
空格- 子内容2

8、有序列表

  1. 内容1
  2. 内容2
    注: 两个列表之间不能相邻,否则会解释为嵌套的列表

9、链接工具

  • 地址: [ 文字 ] (超链接地址)
  • 图片: ![ 图片名,没有则空格代替 ] (本地或者url图片地址)
    • 限制图片大小并居中
1
2
<img src="图片地址" width="图片显示宽度" height="显示高度"  
alt="图片名称"/>设置图片大小,再用<div align=center></div>命令包裹达到居中效果。

10、公式

LaTeX公式转化工具

  • 引用转化后的<img…/>代码
    • 实例:

11、表格

  • 代码第一行表示表头,第二行分隔表头和主体部分,从第三行每一行表示一个表格行
  • 案例:
    python | R |MATLAB|
    ——- |—–|—-|
    列表一 | 列表二 | 列表三|
    1 | 3 | 4 |

参考

https://www.zybuluo.com/mdeditor?url=https://www.zybuluo.com/static/editor/md-help.markdown#cmd-markdown
http://www.tuicool.com/articles/fmeMbqR
 惬意生活

爬虫进阶

数据提取方法

json

  • 数据交换格式(后端转换到前端),看起来像python类型(字典、集合…)的字符串
  • 使用json之前需要导入模块
  • 哪里会返回json数据
    • 浏览器切换到手机版
    • 抓包app
  • jsom.loads
    • 把json字符串转化为python类型
    • json.loads('json字符串')
  • json.dump
    • 把python类型转化为json字符串
    • json.dumps('{python字典}')
    • json.dumps(ret1,ensure_ascii=False,indent=2)
      • ensure_ascii : 让中文显示成中文
      • indent: 能够让下一行在上一行的基础上空格, indent = 2
  • 豆瓣电视爬虫案例
    • preview搜索需要的爬取的内容
    • Filter 过滤显示输入字段的url地址
    • 案例实现代码:
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
#coding=gbk
from parse import parse_url
import json

class DoubanSpider:
"""豆瓣内容抓取"""
def __init__(self):
#最开始的入口
self.temp_url = "https://movie.douban.com/j/search_subjects?type=tv&tag=%E7%BE%8E%E5%89%A7&sort=recommend&page_limit=20&page_start={}" # {}大括号里对应字段传入值num的.format(num)

def get_content_list(self,html_str): #提取数据
dict_data = json.loads(html_str) #有callback就删除
content_list = dict_data["subjects"]
#total = dict_data["total"] 没有total的话自己设置
return content_list #,total

def save_content_list(self,content_list):
with open("douban.json","a") as f:
for content in content_list:
f.write(json.dumps(content,ensure_ascii=False))
f.write("\n")
print('保存成功')

def run(self): #实现主要逻辑
num = 0
#total = 100 初始化total,第二页更新时不使用
while num < 100: #num < total+ page_limit 全部提取数据
#1.start_url
url = self.temp_url.format(num) #对start进行复制
print(url)
#2.发送请求,获取响应
html_str = parse_url(url)
#3.提取数据
content_list = self.get_content_list(html_str) #content,tatal =
#4.保存
self.save_content_list(content_list)
#5.构造下一页的url,循环2-5步
num += 20

if __name__ == '__main__':
douban = DoubanSpider() #实例化
douban.run()

xpath和lxml

xpath

  • 一门从html中提取数据的语言
    • xpath语法
  • xpath helper插件:帮助我们从element中定位数据
    • 1.选择节点(标签)
    • /html/head/meta: 能够选中html下的所有meta标签
    • 2.// : 能够选择任意标签
    • //li: 当前页面上所有li标签
    • /html/meta//link: 结合使用显示meta下的link标签
    • 3.@符号用途
    • 选择具体属性值
    • //div[@class='feed-infinite-wrapper']/ul/li: 选择class=’feed-infinite-wrapper’的div下的ul下的li
    • //div[@class='feed-infinite-wrapper']/ul/li/a/@href:选择a标签的href值
    • 4.获取a标签下的文本: /a/text()
    • 标签下的所有文本: /a//text()
    • 5.点前
    • “./a” 当前节点下的a标签

lxml

  • 安装: pip install lxml
    • 使用:
      from lxml import etree
      element = etree.HTML(‘接受的html字符串’) #转化为element对象
      element.xpath(“”) #url地址对应响应,网页源码,只有elements和url响应相同时才能看elements
  • 实现代码:
    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
    #coding=gbk
    import requests
    from lxml import etree

    url = "https://movie.douban.com/chart"
    headers = {
    "User_Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36",
    }

    response = requests.get(url,headers=headers)
    html_str = response.content.decode()

    #print(html_str)

    #使用etree处理数据
    html = etree.HTML(html_str)
    #print(html)

    #1.获取所有电影图片地址
    img_list = html.xpath("//div[@class='indent']/div/table//a[@class='nbg']/img/@src")
    #print('movie_img地址: \n\t'+str(img_list)

    #2.获取所有电影的url地址
    url_list = html.xpath("//div[@class='indent']/div/table//div[@class='pl2']/a/@href")
    #print(url_list)

    #3.每部电影元素组成字典,字典中包含标题、url、图片地址、评论数、评分
    #思路:
    #(1)分组
    #(2)每一组提取数据

    ret1 = html.xpath("//div[@class='indent']/div/table")
    #print(ret1) #这是一个列表式element对象,即标签节点

    for table in ret1:
    #当[0]为空时会报错,先判断是否为null
    item = {} #空集合
    item['title'] = table.xpath(".//div[@class='pl2']/a/text()")[0].replace('/','').strip()#当前节点下续写
    item['href'] = table.xpath(".//div[@class='pl2']/a/@href")[0]
    item['img'] = table.xpath(".//a[@class='nbg']/img/@src")[0]
    item['comment_num'] = table.xpath(".//span[@class='pl']/text()")[0]
    item['rating_num'] = table.xpath(".//span[@class='rating_nums']/text()")[0]
    #列表推导式
    #item["title"] = [for i in item["title"]] #正则
    print(item)

xpath和lxml案例(糗事百科)

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
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
#coding=gbk
from lxml import etree
import requests
import json

class QiubaiSpader:
def __init__(self):
self.url_temp = "https://www.qiushibaike.com/8hr/page/{}/"
self.headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36",
}

def get_url_list(self): #根据url地址规律构造url_list
url_list = [self.url_temp.format(i) for i in range(1,14)]
return url_list

def parse_url(self,url): #发送请求获取响应
print('now_parse:'+url)
response = requests.get(url,headers=self.headers)
return response.text.encode('GBK','ignore').decode('gbk')

def get_content_list(self,html_str): #从字符串响应中提取数据
html = etree.HTML(html_str)
content_list = []
#1.分组
div_list = html.xpath('//div[@id="content-left"]/div')
for div in div_list:
item = {}
#获取的字符串[0]指的是去除两边换行\n,取除字符串
item["author_name"] = div.xpath(".//h2/text()")[0].strip() if len(div.xpath(".//h2/text()"))>0 else None #提取用户名
item["author_img"] = div.xpath(".//img/@src")
#内容
item["content"] = div.xpath('.//div[@class="content"]/span/text()') #<br>将字符串隔断
item["content"] = [i.strip() for i in item["content"]]
item["stats_vote"] = div.xpath('.//span[@class="stats-vote"]/i/text()')
#好笑数
item["stats_vote"] = item["stats_vote"][0] if len(item["stats_vote"])>0 else None
item["stats-comments"] = div.xpath('.//span[@class="stats-comments"]//i/text()')
#评论数
item["stats-comments"] = item["stats-comments"][0] if len(item["stats-comments"])>0 else None
item["content_img"] = div.xpath('.//div[@class="thumb"]//img/@src')
#内容图片不完整加上获取
item["content_img"] = 'https:' + item["content_img"][0] if len(item["content_img"])>0 else None
content_list.append(item)
return content_list #返回json格式

def save_content_list(self,content_list):#保存
with open('qiubai.txt','a',encoding='utf-8') as f:
for content in content_list:
#转化为字符串
f.write(json.dumps(content,ensure_ascii=False))
f.write('\n')
print("保存成功")

def run(self):
"""实现主要逻辑"""
#1.根据url地址规律来构造url列表
url_list = self.get_url_list()
#2.发送请求获取响应
for url in url_list: #遍历一一爬取每个页面内容
html_str = self.parse_url(url)
#3.提取数据
content_list = self.get_content_list(html_str)
#4.保存
self.save_content_list(content_list)

if __name__ == '__main__':
qiubai = QiubaiSpader()
qiubai.run()

写爬虫的套路

  • 1.url
    • 知道url地址规律和总页码: 构造url地址的列表
    • start_url、先构造起始url地址,然后构造下一页面
  • 2.发送请求获取响应
    • request(parse方法)
  • 3.提取数据
    • 返回json字符串:json模块
    • 返回的是html字符串:lxml模块配合xpath提取数据
  • 4.保存
    • 保存到文本,或者数据库

基础知识点的学习

  • format:字符串格式化一种方式
1
2
3
4
"传智{}播客".format("1")
"传智{}播客".format(1)
"传智{}播客".format([1,2,3])
"传智{}播客{}".format({1,2,3},[1,2,3])
  • 列表推导式
    • 帮助我们快速的生成包含一对数据的列表
      [i+10 for i in range(10)] —> [10,11,12…19]
      ["10月{}日".format(i) for i in range(1,10)] —> [“10月1日”,”10月2日”,..,”10月9日”]
  • 字典推导式
    • 帮助我们快速的生成包含一对数据的字典
1
2
{i+10:i for i in range(10)} #{10:0,11:1..10:9}
{"a{}".format(i):10 for i in range(3)} # {"a0":10,"a1":10,"a2":10}
  • 三元运算符
    • if去前面的条件成立就把if前面的结果赋值给a,否则把else后面的结果赋值给a
a = 10 if 4 > 3 else 20   # a = 10
a = 10 if 4 < 3 else 20   # a = 20

爬虫初阶

爬虫概念、工具和HTTP

1、什么是爬虫

  • 爬虫就是模拟客户端(浏览器)发送网络请求,获取服务器响应,按照规则提取数据的程序

2、爬虫数据去哪了

  • 网页呈现出来(不是做新闻的app通过爬虫抓取新闻)
  • 进行分析 (从数据中分析想要的(大公司拥有大数据,小公司抓取数据)
    实例: 爬取小说、新闻等呈现到前端页面

3、 浏览器的请求

  • url
    • 在chrome中点击检查,点击网络network
    • url = 请求协议 + 网络域名、主机名 + 资源路径 +? 参数
  • 小技巧: url解码工具: 将url地址解码,可以将参数具体
  • 浏览器请求url出现大量字符串元素(网页元素由大量工具编写js、css)
    • 当前url对应响应 + js + css + 图片 —–即elements中的内容
  • 爬虫请求url地址
    • 当前url对应响应
  • elements的内容和爬虫获取的url地址对应的响应不同,爬虫中需要以当前url地址对应响应为准提取数据
  • 当前url地址对应的响应在哪
    • 从network中找到当前url地址,点击response
    • 或者在页面上右键显示网页源码(对于更新快的网页,网页源码中元素可能不断改变)

4、 认识HTTP、HTTPS

  • HTTP: 超文本传输协议
    • 以明文形式传输
    • 效率高、不安全
  • HTTPS: HTTP+SSL(安全套接字层)
    • 每次传输之前数据先加密,之后解密获取
    • 效率低、安全
  • get请求和post请求的区别
    • get请求没有请求体,post含有,get请求把数据放到url地址中
    • post请求常用于登录注册
    • post请求携带的数据量比get请求大,多,常用于传输大文本
  • HTTP之请求
    Request Header
    view parms
    • 请求行
    • 请求头 Host、Connection、cache-Control、 User-Agent用户代理:(对方服务器了解访问者是什么浏览器、还是爬虫)
      如果我们需要模拟手机版浏览器则修改User-Agent,并选择相应型号手机
      • Cookie: 用来存储用户信息、每次请求会被携带上发送给对方的浏览器
      • 要获取登录后才能访问的页面
      • 对方的服务器会通过cookie来判断我们是否是一个爬虫
    • 请求体
    • 携带数据
    • get请求没有请求体,post含有
  • HTTP协议之响应
    • 1.响应头
    • Set-Cookie: 对方服务器通过该字段设置Cookie(cookies查看)到本地
    • 2.响应体
    • url地址对应的响应

requests模块

1、 使用前安装

pip install requests

2、 get/post响应请求

  • response = requests.get(url) #发送get请求,请求url地址对应的响应
  • response = requests.post(url, data = {请求的字典}) #发送post请求并附带请求体,请求url地址对应的响应
1
2
3
4
5
6
7
8
9
10
import requests
url = " "
query_string = {"query":".....",
"from":"zh",
"to":"en}
headers = {"User-Agent":"......"网页Fn+12赋值}

response = requests.post(url,data = query_string,headers = headers)
print(response) #判断请求正常发送出去,服务器响应
print(response.content.decode())

3、response方法

  • response.text
    大部分都会出现乱码,一般加上resonse.encoding = ‘utf-8’
  • response.content.decode()
    二进制字节流byte形式显示,一般加上decode()转化为str类型
  • response.encoding = response.apparent_encoding
    通过网页内容分析编码
  • response.request.url #发送请求的url地址,字符串
  • response.url #response相应的url地址,页面跳转和前面一个不一样
  • response.request.headers #请求头,字典
  • response.headers #响应头

4、获取网页源码正确打开方式

  1. response.content.decode()
  2. response.content.decode(“gbk”)
  3. response.text #requests根据头部猜测,该方式往往出现乱码,解决response.encoding=’utf-8’
  4. response.text.encode(‘GBK’,’ignore’).decode(‘gbk’)

5、发送header请求

  • 目的为了模拟浏览器,获取和浏览器一模一样的内容
    headers = {“User-Agent”:……网页Fn+12赋值}
    “Referer”:”…..”
    更多的参数尝试

response = requests.get(url,headers = headers)
response = requests.post(url,data = data,headers=headers)

6、使用超时参数

  • requests.get(url,headers = headers,timeout=3) #3秒内必须返回,否则报错

7、retrying模块学习

  • pip install retrying
1
2
3
4
5
6
from retrying import retry

@retry(stop_max_attempt_number=3) #让被装饰的函数,反复请求3次,三次报错才报错,只要有一次正确请求则返回
def fun1():
print("this is fun1")
raise ValueErro("this is test error) #报错效果

8、详细代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
headers = {"User-Agent":"....."}

@retry(stop_max_attempt_number=3)
def _parse_url(url):
print("*"*100) #检测
response = requests.get(url,headers=headers,timeout)
return response.content.decode()

def parse_url(url):
try:
html_str = _parse_url(url)
except:
html_str = None
return html_str

if __name__ == '__main__': #本模块执行
url = "http://www.baidu.com"
print(parse_url(url)[:100]) #取字符串前100

9、requests处理Cooike相关请求

  • 人人网(“email”:”mr_mao_hacker@163.com“,”password”:”alarmchime”)
  • 方式一: 直接携带Cooike请求url地址
  1. cookie放在headers中
    1.1 headers = {“User-Agent”:”…”,
    “Cookie”:”…”}
  2. cookie字典传给cookies参数
    requests.get(url,cookies = cookie_dict)
  • 方式二: 先发送post请求,获取cookie,带上cookie请求登录后的页面
  1. session = requests.session() # 帮助和服务端回话保持| 方法和request相同
  2. session.post(url,data,headers) #服务器设置在本地的cookie会保存在session中
  3. session.get(url) #会带上之前保存在session中的cookie,能够请求成功

10、在使用session 请求登录后的页面

1
2
3
4
url = "....."
response = session.get(url,headers=headers)
with open("renren3.html","w",encoding='utf-8') as f:
f.write(response.content.decode()

11、三种方式爬虫案例

1.requests-get实现页面爬取(百度首页)

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
#coding=utf-8

import requests
from retrying import retry


headers = {
"User-Agent": "Mozilla/5.0 (iPhone; CPU iPhone OS 11_0 like Mac OS X) AppleWebKit/604.1.38 (KHTML, like Gecko) Version/11.0 Mobile/15A372 Safari/604.1",
}

@retry(stop_max_attempt_number=3) #装饰函数反复请求,三次请求都失败报错
def get_page(get_url):
"""get()方法请求内容"""
print('*'*10) #用于检测请求次数
r = requests.get(get_url,headers=headers,timeout=10)
return r.text.encode('GBK','ignore').decode('gbk') #解决不支持'gbk'

def _get_page(get_url):
try:
html_str = get_page(get_url)
except:
html_str = 'Error'
else:
with open('baidu_get.text','w') as f:
f.write(html_str[:500]) #正确执行写入文件
return html_str

if __name__ == '__main__':

get_url = 'https://www.baidu.com/'
print(_get_page(get_url)[:500]) #请求前100字符串

2.requests-post实现携带请求体爬取输入框转化内容(百度翻译)

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
#coding=gbk
import requests
from retrying import retry
import json

headers = {
"User-Agent": "Mozilla/5.0 (iPhone; CPU iPhone OS 11_0 like Mac OS X) AppleWebKit/604.1.38 (KHTML, like Gecko) Version/11.0 Mobile/15A372 Safari/604.1",
"Referer": "http://fanyi.baidu.com/?aldtype=16047",
}
query_data = {
"query": "人生苦短,我用python", #此处可以用input输入字符串
"from": "zh",
"to": "en",
}

@retry(stop_max_attempt_number=3) #连续请求三次,三次都失败报错
def get_page(url):
"""服务器请求"""
print("*"*10) #服务器请求检验
r = requests.post(url,headers=headers,data=query_data,timeout=3)
return r.content.decode()

def _get_page(url):
try:
html_str = get_page(url)
except:
html_str = None
return html_str

if __name__ == '__main__':
url = 'http://fanyi.baidu.com/basetrans'
#print(_get_page(url)) #输出类似字典,但是json字符串
page_dict = json.loads(_get_page(url))
print(page_dict['trans'][0]['dst'])

3.cookies请求登录后服务器保留密码的页面(人人网)

  • headers直接携带cookie请求
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
#coding=gbk
import requests
from retrying import retry

#将请求成功的cookie信息放入headers,直接携带请求
headers = {
"User_Agent":"Mozilla/5.0 (iPhone; CPU iPhone OS 11_0 like Mac OS X) AppleWebKit/604.1.38 (KHTML, like Gecko) Version/11.0 Mobile/15A372 Safari/604.1",
"Cookie": "anonymid=jl6plze3-antvfl; _r01_=1; ln_uact=17318646019; ln_hurl=http://head.xiaonei.com/photos/0/0/men_main.gif; _de=71EA9E23AC1F39D48A6CD3B85E99E01A; depovince=SC; JSESSIONID=abcnrx7CjMin0-AScWtww; ick_login=9a8e1f1c-6cd8-4700-afa6-8cf5315d36c2; jebe_key=8be431ea-e18e-4feb-ab4b-0472222a3513%7C819b727b2164a924b41678741330f60a%7C1535114212567%7C1%7C1535782169180; _ga=GA1.2.609958396.1535782958; _gid=GA1.2.2069950083.1535782958; jebecookies=2f5e7612-0f24-4f28-a1ff-52b96074e414|||||; p=fddc828d0aeca708377ca86756cd44342; first_login_flag=1; t=84129fe73a07099108643adb89c95ad52; societyguester=84129fe73a07099108643adb89c95ad52; id=967724772; xnsid=6c333906; ver=7.0; loginfrom=null; wp_fold=0",
}

@retry(stop_max_attempt_number=3)
def get_page(url):
"""请求服务器响应"""
print('*'*10)
response = requests.get(url,headers=headers,timeout=5)
return response.content.decode()

def _get_page(url):
try:
html_str = get_page(url)
except:
html_str = None
return html_str

if __name__ == '__main__':
url = 'http://www.renren.com/967724772/profile'
with open('renren2.txt','w',encoding='utf-8') as f:
f.write(_get_page(url))
  • cookie作为字符串+字典推导式(人人网)
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
#coding=gbk
import requests
from retrying import retry

headers = {
"User_Agent":"Mozilla/5.0 (iPhone; CPU iPhone OS 11_0 like Mac OS X) AppleWebKit/604.1.38 (KHTML, like Gecko) Version/11.0 Mobile/15A372 Safari/604.1",
#"Referer": "http://www.renren.com/967724772"
}

#cookie字符串
cookie="anonymid=jl6plze3-antvfl; _r01_=1; ln_uact=17318646019; ln_hurl=http://head.xiaonei.com/photos/0/0/men_main.gif; _de=71EA9E23AC1F39D48A6CD3B85E99E01A; depovince=SC; jebe_key=8be431ea-e18e-4feb-ab4b-0472222a3513%7C819b727b2164a924b41678741330f60a%7C1535114212567%7C1%7C1535782169180; _ga=GA1.2.609958396.1535782958; _gid=GA1.2.2069950083.1535782958; fenqi_user_city=36; jebecookies=35d2c64d-78b8-41ef-b5e4-4c887424f2ac|||||; JSESSIONID=abcJLhFJVpWjx73Ufvyww; ick_login=f74bfdc3-17bf-44a5-8227-33b2b0e79e89; p=f527cef24d899db1c7795ed77b5494772; first_login_flag=1; t=f634330753378f3c9eb40dd69dcd74c72; societyguester=f634330753378f3c9eb40dd69dcd74c72; id=967724772; xnsid=67ab8568; ver=7.0; loginfrom=null; wp_fold=0"

cookie_dict = {i.split("=")[0]:i.split("=")[-1]for i in cookie.split("; ")} #字典推导式,将字符串转化为字典
#print(cookie_dict)

@retry(stop_max_attempt_number=3)
def get_page(url):
print('*'*10)
r = requests.get(url,headers=headers,cookies=cookie_dict,timeout=3)
return r.content.decode()

def _get_page(url):
try:
html_str = get_page(url)
except:
html_str = None
return html_str

if __name__ == '__main__':
url = "http://www.renren.com/967724772/profile"
with open('renren2.txt','w') as f:
f.write(_get_page(url))

4. post请求页面,保存登录后的cookies信息到本地session

  • 注意: 验证码待解决,没有实现session访问,存有疑问!!!
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
#coding=gbk
import requests
from retrying import retry

headers = {
"User_Agent":"Mozilla/5.0 (iPhone; CPU iPhone OS 11_0 like Mac OS X) AppleWebKit/604.1.38 (KHTML, like Gecko) Version/11.0 Mobile/15A372 Safari/604.1",
#"Referer": "http://www.renren.com/967724772"
}
#登录界面输入框内容和action网址
query_data = {
"email":"17318646019",
"password":"******",
}

#实例化session
session = requests.session()

@retry(stop_max_attempt_number=3)
def _get_page(post_url,url):
#先发送post请求,获取cookie,带上cookie请求登录后的页面
session.post(post_url,headers=headers,data=query_data) #本地cookie保存到session
#使用session请求登录后的页面
response = session.get(url,headers=headers)
return response.content.decode()


if __name__ == '__main__':
post_url = "http://www.renren.com/PLogin.do"
url = "http://www.renren.com/967724772/profile"
with open('renren_session_cookie.txt','w',encoding='utf-8') as f:
f.write(_get_page(post_url,url))

正则表达式

  • 获取成对标签 之间的内容
1
2
res_tr = r'<tr>(.*?)</tr>'      # re.M 改变'^'和'$'行为和 re.S改变'.'的行为
m_tr = re.findall(res_tr,language,re.S|re.M)
  • 获取超链接之间的内容
1
2
res_tr = r'<a .*?>(.*?)</a>'  
m_tr= re.findall(res_tr, content, re.S|re.M)
  • 获取所有链接所有内容,包含href
1
2
3
4
5
6
7
8
urls=re.findall(r"<a.*?href=.*?<\/a>", content, re.I|re.S|re.M)
```

- 获取<a href></a>中的URL

```python
res_url = r"(?<=href=\").+?(?=\")|(?<=href=\').+?(?=\')"
link = re.findall(res_url , content, re.I|re.S|re.M)
  • 爬取网页标题title两种方法
    • method
1
2
3
4
5
title_pat = r'(?<=<title>).*?(?=</title>)'    
title_ex = re.compile(title_pat,re.M|re.S)
title_obj = re.search(title_ex, content)
title = title_obj.group()
print title
  • method
1
2
title = re.findall(r'<title>(.*?)</title>', content)  
print title[0]
  • 定位table位置并爬取属性-属性值
1
2
3
4
start = content.find(r'<table class="infobox vevent"') #起点记录查询位置    
end = content.find(r'</table>')
infobox = language[start:end]
print infobox #得到start-end之间的结构体
  • 去掉内容里面的 br换行 和’\n’换行空格
1
2
3
if '<br />' in value:
value = value.replace('<br />','') #过滤该标签
value = value.replace('\n',' ') #换行空格替代 否则总换行
  • 过滤HTML标签
1
value = re.sub('<[^>]+>','', value)      #过滤HTML标签
,