python爬虫

Posted by Procon on April 6, 2020

Urllib

1.反爬手段?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
1.User‐Agent:
	User Agent中文名为用户代理,简称 UA,它是一个特殊字符串头,使得服务器能够识别客户使用的操作系统及版
本、CPU 类型、浏览器及版本、浏览器渲染引擎、浏览器语言、浏览器插件等。

2.代理IP
	西次代理
	快代理
	什么是高匿名、匿名和透明代理?它们有什么区别?
		1.使用透明代理,对方服务器可以知道你使用了代理,并且也知道你的真实IP。
		2.使用匿名代理,对方服务器可以知道你使用了代理,但不知道你的真实IP。
		3.使用高匿名代理,对方服务器不知道你使用了代理,更不知道你的真实IP。
3.验证码访问
	打码平台
	云打码平台
	超级🦅
4.动态加载网页 网站返回的是js数据 并不是网页的真实数据
	selenium驱动真实的浏览器发送请求
5.数据加密
	分析js代码

2.urllib库使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
urllib.request.urlopen() 模拟浏览器向服务器发送请求
response 服务器返回的数据
	response的数据类型是HttpResponse
	字节‐‐>字符串
		解码decode
	字符串‐‐>字节
		编码encode
	read() 字节形式读取二进制 扩展rede(5)返回前几个字节
	readline() 读取一行
	readlines() 一行一行读取 直至结束
	getcode() 获取状态码
	geturl() 获取url
	getheaders() 获取headers
	urllib.request.urlretrieve()
		请求网页
		请求图片
		请求视频

3.请求对象的定制

1
2
3
4
UA介绍:User Agent中文名为用户代理,简称 UA,它是一个特殊字符串头,使得服务器能够识别客户使用的操作系统
及版本、CPU 类型、浏览器及版本。浏览器内核、浏览器渲染引擎、浏览器语言、浏览器插件等

语法:request = urllib.request.Request()

扩展:编码的由来

4.编解码

1.get请求方式:urllib.parse.quote()

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
import urllib.request
import urllib.parse

url = 'https://www.baidu.com/s?wd='

# url的组成
# https://www.baidu.com/s?wd=周杰伦

# http/https    www.baidu.com   80/443     s      wd = 周杰伦     #
#    协议             主机        端口号     路径     参数           锚点
# http   80
# https  443
# mysql  3306
# oracle 1521
# redis  6379
# mongodb 27017

headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) '
                  'Chrome/111.0.0.0 Safari/537.36 Edg/111.0.1661.51'
}

# 因为urlopen方法中不能存储字典 所以headers不能传递进去
# 请求对象的定制
url = url + urllib.parse.quote('性交')

request = urllib.request.Request(url=url, headers=headers)

response = urllib.request.urlopen(request)

content = response.read().decode('utf8')

2.get请求方式:urllib.parse.urlencode()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
    url = 'https://www.baidu.com/s?'
    data = {
        'name': '小刚',
        'sex': '',
    }
    headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) '
                      'Chrome/111.0.0.0 Safari/537.36 Edg/111.0.1661.51'
    }
    data = urllib.parse.urlencode(data)
    url = url + data
    print(url)

    request = urllib.request.Request(url=url, headers=headers)

    response = urllib.request.urlopen(request)

    content = response.read().decode('utf8')

    print(content)

3.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
35
36
import urllib.parse

import urllib.request

import json

url = 'https://fanyi.baidu.com/v2transapi?from=en&to=zh'
headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) '
                  'Chrome/111.0.0.0 Safari/537.36 Edg/111.0.1661.51',
    'Cookie': 'BIDUPSID=DF9744CD34BAE05BB8671D82A507C548; PSTM=1678365929; newlogin=1; BDUSS=VhwWk9qV2ZtRzFmYndLRHBEMHJ0YlZpRWhkMDZKM295aEJYSTdISUY0Y1RaekZrSVFBQUFBJCQAAAAAAAAAAAEAAADdrDBA2K-7qML6wqXs4bniueIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABPaCWQT2glkM; BDUSS_BFESS=VhwWk9qV2ZtRzFmYndLRHBEMHJ0YlZpRWhkMDZKM295aEJYSTdISUY0Y1RaekZrSVFBQUFBJCQAAAAAAAAAAAEAAADdrDBA2K-7qML6wqXs4bniueIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABPaCWQT2glkM; BAIDUID=DF9744CD34BAE05BA1B7B38C3A014179:SL=0:NR=10:FG=1; BDORZ=B490B5EBF6F3CD402E515D22BCDA1598; BA_HECTOR=ak0h24a4240k212l2l2l858t1i1vf1q1m; ZFY=vprJv3LpLohE:BtuLaK:BL6qr1eZ3UZy27q1f4CAIHDeg:C; BAIDUID_BFESS=DF9744CD34BAE05BA1B7B38C3A014179:SL=0:NR=10:FG=1; BDRCVFR[feWj1Vr5u3D]=I67x6TjHwwYf0; PSINO=3; delPer=0; H_PS_PSSID=38185_36543_38410_38368_38403_37862_38468_38170_38290_38250_37924_38382_38040_26350_38418_38282_37881; APPGUIDE_10_0_2=1; REALTIME_TRANS_SWITCH=1; FANYI_WORD_SWITCH=1; HISTORY_SWITCH=1; SOUND_SPD_SWITCH=1; SOUND_PREFER_SWITCH=1; ab_sr=1.0.1_NDAzMGYwMzU3MTViM2Q4ODFiZWEyMzMyNWI1ZmVhOTI1ODEzMmI1MjEyMTVkYTJlZDQzNmM3MWRkMGIwNDUzNmQzMjljNmZiMTEwMmU4OTU1OTQ1Zjg0NWU2ZTU4NzQ2NzU2ZTkwNTNhMDY0NGZkNTA4ZjY4MDgxY2Y2YjRmMGQxZDYxMmMwOTY4YjliOTM4OGQwZDliZmY5OTU4NzBlOGQ1OGUyMDZiNWI1MGE3NWJmM2FiMDkwYzI0YTkwZTZi'
}
keyword = input("请输入要查询的单词:")
data = {
    'from': 'zh',
    'to': 'en',
    'query': keyword,
    'transtype': 'translang',
    'simple_means_flag': '3',
    'sign': '569746.807587',
    'token': '03b7d79aace86efda4176a7e8edef1a1',
    'domain': 'common'
}
# post请求的参数  必须进行编码 并且要调用encode方法
data = urllib.parse.urlencode(data).encode('utf-8')
# 请求对象的定制
request = urllib.request.Request(url=url, data=data, headers=headers)

# 模拟浏览器向服务器发送请求
response = urllib.request.urlopen(request)
# 获取响应的数据
content = response.read().decode('utf-8')

obj = json.loads(content)
print(obj)

总结:post和get区别?

1
2
1:get请求方式的参数必须编码,参数是拼接到url后面,编码之后不需要调用encode方法
2:post请求方式的参数必须编码,参数是放在请求对象定制的方法中,编码之后需要调用encode方法

5.ajax的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
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
70
# https://movie.douban.com/j/chart/top_list?type=5&interval_id=100%3A90&action=&
# start=0&limit=20

# https://movie.douban.com/j/chart/top_list?type=5&interval_id=100%3A90&action=&
# start=20&limit=20

# https://movie.douban.com/j/chart/top_list?type=5&interval_id=100%3A90&action=&
# start=40&limit=20

# https://movie.douban.com/j/chart/top_list?type=5&interval_id=100%3A90&action=&
# start=60&limit=20

# page    1  2   3   4
# start   0  20  40  60

# start (page - 1)*20


# 下载豆瓣电影前10页的数据
# (1) 请求对象的定制
# (2) 获取响应的数据
# (3) 下载数据

import urllib.parse
import urllib.request


def create_request(page_no):
    base_url = 'https://movie.douban.com/j/chart/top_list?type=5&interval_id=100%3A90&action=&'

    data = {
        'start': (page_no - 1) * 20,
        'limit': 20
    }

    data = urllib.parse.urlencode(data)

    url = base_url + data

    headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) '
                      'Chrome/92.0.4515.159 Safari/537.36'
    }

    return urllib.request.Request(url=url, headers=headers)


def get_content(request_obj):
    response = urllib.request.urlopen(request_obj)
    return response.read().decode('utf-8')


def down_load(page_no, res_content):
    with open('douban_' + str(page_no) + '.json', 'w', encoding='utf-8') as fp:
        fp.write(res_content)


# 程序的入口
if __name__ == '__main__':
    start_page = int(input('请输入起始的页码'))
    end_page = int(input('请输入结束的页面'))

    for page in range(start_page, end_page + 1):
        #         每一页都有自己的请求对象的定制
        request = create_request(page)
        #         获取响应的数据
        content = get_content(request)
        #         下载
        down_load(page, content)

6.ajax的post请求

案例:KFC官网

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
# 1页
# http://www.kfc.com.cn/kfccda/ashx/GetStoreList.ashx?op=cname
# post
# cname: 北京
# pid:
# pageIndex: 1
# pageSize: 10


# 2页
# http://www.kfc.com.cn/kfccda/ashx/GetStoreList.ashx?op=cname
# post
# cname: 北京
# pid:
# pageIndex: 2
# pageSize: 10

import urllib.request
import urllib.parse


def create_request(page):
    base_url = 'http://www.kfc.com.cn/kfccda/ashx/GetStoreList.ashx?op=cname'

    data = {
        'cname': '北京',
        'pid': '',
        'pageIndex': page,
        'pageSize': '10'
    }

    data = urllib.parse.urlencode(data).encode('utf-8')

    headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) '
                      'Chrome/92.0.4515.159 Safari/537.36'
    }

    request = urllib.request.Request(url=base_url, headers=headers, data=data)

    return request


def get_content(request):
    response = urllib.request.urlopen(request)
    content = response.read().decode('utf-8')
    return content


def down_load(page, content):
    with open('kfc_' + str(page) + '.json', 'w', encoding='utf-8') as fp:
        fp.write(content)


if __name__ == '__main__':
    start_page = int(input('请输入起始页码'))
    end_page = int(input('请输入结束页码'))

    for page in range(start_page, end_page + 1):
        # 请求对象的定制
        request = create_request(page)
        # 获取网页源码
        content = get_content(request)
        # 下载
        down_load(page, content)

7.URLError\HTTPError

1
2
3
4
5
6
7
简介:
	1.HTTPError类是URLError类的子类
	2.导入的包urllib.error.HTTPError urllib.error.URLError
	3.http错误:http错误是针对浏览器无法连接到服务器而增加出来的错误提示。引导并告诉浏览者该页是哪里出
了问题。
	4.通过urllib发送请求的时候,有可能会发送失败,这个时候如果想让你的代码更加的健壮,可以通过tryexcept
进行捕获异常,异常有两类,URLError\HTTPError
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
import urllib.request
import urllib.error
url = 'https://blog.csdn.net/ityard/article/details/102646738'
headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) '
                  'Chrome/111.0.0.0 Safari/537.36 Edg/111.0.1661.51',
    'Cookie': 'uuid_tt_dd=10_30844396170-1678371350421-410462; c_adb=1; UserName=Solo_guanggaung; '
              'UserInfo=85bbd718ef3c428485beae0a3c34d10f; UserToken=85bbd718ef3c428485beae0a3c34d10f; '
              'UserNick=%E9%9A%90%E8%BA%AB%E6%89%8D%E6%98%AF%E6%9C%AC%E4%BD%93; AU=434; UN=Solo_guanggaung; '
              'BT=1678376092017; p_uid=U010000; '
              'Hm_up_6bcd52f51e9b3dce32bec4a3997715ac=%7B%22islogin%22%3A%7B%22value%22%3A%221%22%2C%22scope%22%3A1'
              '%7D%2C%22isonline%22%3A%7B%22value%22%3A%221%22%2C%22scope%22%3A1%7D%2C%22isvip%22%3A%7B%22value%22%3A'
              '%220%22%2C%22scope%22%3A1%7D%2C%22uid_%22%3A%7B%22value%22%3A%22Solo_guanggaung%22%2C%22scope%22%3A1'
              '%7D%7D; firstDie=1; Hm_lvt_6bcd52f51e9b3dce32bec4a3997715ac=1678428902,1678886386,1679568376,'
              '1679798814; Hm_ct_6bcd52f51e9b3dce32bec4a3997715ac=6525*1*10_30844396170-1678371350421-410462!5744*1'
              '*Solo_guanggaung; c_segment=14; dc_sid=5a571b950c4ab749f0ca7cb220c9e13f; '
              'dc_session_id=10_1679815417602.564103; c_first_ref=www.google.com; '
              'c_first_page=https%3A//www.csdn.net/; c_dsid=11_1679817036063.303856; log_Id_view=249; '
              'log_Id_click=26; ssxmod_itna=Qqfx0iwxBDgD2Dl4iwlxjxCTkZRI+KDOI+e53sDBMhY4iNDnD8x7YDv+IvFQQ'
              '=e17rKa5Keg2Yqj7jQEApqlA8EXPrDCPGnDB9DrV+DYAkDt4DTD34DYDixibCxi5GRD0KDFF5XUZ9Dm4GW9qDgn4GgDCiD0'
              '+Uc3wiD4qDB+rdDKM0cDGY6YmUdpkG=sBhcD0UqxBd4WcGcICcF=iX=56nDaEQDzkHDtut5wMbDC2=/UdiTIiPb+05rU+DFmRhoDg'
              '+bUFmTK7hPlKoGFYkr/DQolo1DGSxqmD1xD; '
              'ssxmod_itna2=Qqfx0iwxBDgD2Dl4iwlxjxCTkZRI+KDOI+e5ID8dZ+BxGXdPGazKFIHUuzx8gOIhOqzolyisDNblBrrov1Cxnz'
              '+IZjoi+Kx+PAiXxvrGfcoWxbUEaI3MFQSMjYvsId1yBPyttRM0tbA6SqIM4TYDuM4nfxUwtkUvUk2DX+roMqRljLXxN'
              '+RX8lUEQnrGbWj0ffIE88G8B2YL0GrNGTdqDnfOHeQdrj23qMc54M=GdjKVW9BGN1I7O9vHuAK=TPU1hbLkVagxN1kv2K7QqVAwpK7'
              '/bX1ra/SuqcCXqsZUNl1yTKYtpdW/aNXOpFP3VENxzicefA6Nrm4DQ94U0q80dzGiUGxebqIitAAPsDinY5ZBqF0eD08DiQqYD===; '
              'csrfToken=bHS_4PaJf46yWMg799xXxgUb; c_pref=https%3A//www.google.com/; c_ref=https%3A//www.csdn.net/; '
              'c_page_id=default; dc_tos=rs4b4l; log_Id_pv=53'
}
try:
    request = urllib.request.Request(url=url, headers=headers)
    response = urllib.request.urlopen(request)
    content = response.read().decode('utf‐8')
    print(content)
except urllib.error.HTTPError:
    print(1111)
except urllib.error.URLError:
    print(22222)

8.Handler处理器

1
2
3
4
5
6
7
8
 为什么要学习handler
 	urllib.request.urlopen(url)
 		不能定制请求头
 	urllib.request.Request(url,headers,data)
 		可以定制请求头
 	Handler
 		定制更高级的请求头随着业务逻辑的复杂 请求对象的定制已经满足不了我们的需求动态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

# 需求 使用handler来访问百度  获取网页源码

import urllib.request

url = 'http://www.baidu.com'

headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.159 Safari/537.36'
}

request = urllib.request.Request(url = url,headers = headers)

# handler   build_opener  open

# (1)获取hanlder对象
handler = urllib.request.HTTPHandler()

# (2)获取opener对象
opener = urllib.request.build_opener(handler)

# (3) 调用open方法
response = opener.open(request)

content = response.read().decode('utf-8')

print(content)

9.代理服务器

1
2
3
4
5
6
7
8
9
10
11
12
13
1.代理的常用功能?
	1.突破自身IP访问限制访问国外站点
	2.访问一些单位或团体内部资源
		扩展某大学FTP(前提是该代理地址在该资源的允许访问范围之内)使用教育网内地址段免费代理服务器就可以用于对教育网开放的各类FTP下载上传以及各类资料查询共享等服务
	3.提高访问速度
		扩展通常代理服务器都设置一个较大的硬盘缓冲区当有外界的信息通过时同时也将其保存到缓冲区中当其他用户再访问相同的信息时 则直接由缓冲区中取出信息传给用户以提高访问速度
	4.隐藏真实IP
		扩展上网者也可以通过这种方法隐藏自己的IP免受攻击
2.代码配置代理
	创建Reuqest对象
	创建ProxyHandler对象
	用handler对象创建opener对象
	使用opener.open函数发送请求求
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
import urllib.request

url = 'http://www.baidu.com/s?wd=ip'

headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.159 Safari/537.36'
}

# 请求对象的定制
request = urllib.request.Request(url = url,headers= headers)

# 模拟浏览器访问服务器
# response = urllib.request.urlopen(request)

proxies = {
    'http':'118.24.219.151:16817'
}
# handler  build_opener  open
handler = urllib.request.ProxyHandler(proxies = proxies)

opener = urllib.request.build_opener(handler)

response = opener.open(request)

# 获取响应的信息
content = response.read().decode('utf-8')

# 保存
with open('daili.html','w',encoding='utf-8')as fp:
    fp.write(content)

扩展:1.代理池 2.快代理

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
import urllib.request

proxies_pool = [
    {'http':'118.24.219.151:16817'},
    {'http':'118.24.219.151:16817'},
]

import random

proxies = random.choice(proxies_pool)

url = 'http://www.baidu.com/s?wd=ip'

headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.159 Safari/537.36'
}

request = urllib.request.Request(url = url,headers=headers)

handler = urllib.request.ProxyHandler(proxies=proxies)

opener = urllib.request.build_opener(handler)

response = opener.open(request)

content = response.read().decode('utf-8')

with open('daili.html','w',encoding='utf-8')as fp:
    fp.write(content)

解析

xpath

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
xpath使用
注意提前安装xpath插件
1打开chrome浏览器
2点击右上角小圆点
3更多工具
4扩展程序
5拖拽xpath插件到扩展程序中
6如果crx文件失效需要将后缀修改zip
7再次拖拽
8关闭浏览器重新打开
9ctrl + shift + x
10出现小黑框
1.安装lxml库
	pip install lxml i https://pypi.douban.com/simple
2.导入lxml.etree
	from lxml import etree
3.etree.parse() 解析本地文件
	html_tree = etree.parse('XX.html')
4.etree.HTML() 服务器响应文件
	html_tree = etree.HTML(response.read().decode('utf‐8')
5.html_tree.xpath(xpath路径)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
xpath基本语法
	1.路径查询
		//查找所有子孙节点不考虑层级关系
		/ 找直接子节点
	2.谓词查询
		//div[@id]
		//div[@id="maincontent"]
	3.属性查询
		//@class
	4.模糊查询
		//div[contains(@id, "he")]
		//div[startswith(@id, "he")]
	5.内容查询
		//div/h1/text()
6.逻辑运算
		//div[@id="head" and @class="s_down"]
		//title | //price

JsonPath

1
2
3
4
5
6
jsonpath的安装及使用方式
	pip安装
		pip install jsonpath
	jsonpath的使用
		obj = json.load(open('json文件', 'r', encoding='utf‐8'))
		ret = jsonpath.jsonpath(obj, 'jsonpath语法')

xml最大的优点就有大量的工具可以分析,转换,和选择性的提取文档中的数据。XPath是这些最强大的工具之一。

如果可以使用xpath来解析json,以下的问题可以被解决:

1,数据不使用特殊的脚本,可以在客户端交互的发现并取并获取。

2,客户机请求的JSON数据可以减少到服务器上的相关部分,这样可以最大限度地减少服务器响应的带宽使用率。

如果我们愿意,这个可以解析json数据的工具会变得有意义。随之而来的问题是它如何工作,jsonpath的表达式看起来怎么样。

事实上,json是由c系统编程语言表示自然数据,有特定语言的特定语法来访问json数据。

xpath的表达式:

/store/book[1]/title

我们可以看作是:

x.store.book[0].title

在Javascript, Python 和 PHP 中一个变量x表示json数据。经过观察,特定的语言里有内置xpath来解析数据。

JSONPath工具的问题

-依赖某种特定的语言

- 需要依赖XPath 1.0

- 减少代码量和内存的消耗

- 在运行时

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
JSONPath 表达式

JSONPath 是参照,xpath表达式来解析xml文档的方式,json数据结构通常是匿名的并且不一定需要有根元素。JSONPaht 用一个抽象的名字$来表示最外层对象。

JOSNPath 表达式可以使用.  符号如下:
$.store.book[0].title

或者使用[] 符号
$['store']['book'][0]['title']


从输入路径来看。内部或者输出的路径都会转化成-符号。

JSONPath 允许使用通配符 * 表示所以的子元素名和数组索引。还允许使用 '..' 从E4X参照过来的和数组切分语法 [start:end:step]是从ECMASCRIPT 4 参照过来的。

表达式在下面的脚本语言中可以使用显示的名称或者索引:
$.store.book[(@.length-1)].title


使用'@'符号表示当前的对象,?(<判断表达式>) 使用逻辑表达式来过滤。
$.store.book[?(@.price < 10)].title



这里有个表格,说明JSONPath语法元素和对应XPath元素的对比。

XPath JSONPath Description
/ $ 表示根元素
. @ 当前元素
/ . or [] 子元素
.. n/a 父元素
// .. 递归下降,JSONPath是从E4X借鉴的。
* * 通配符,表示所有的元素
@ n/a 属性访问字符
[] [] 子元素操作符
| [,] 连接操作符在XPath 结果合并其它结点集合。JSONP允许name或者数组索引。
n/a [start: end :step] 数组分割操作从ES4借鉴。
[] ?() 应用过滤表示式
n/a () 脚本表达式,使用在脚本引擎下面。
() n/a Xpath分组

XPath还有很多的语法(本地路径,操作符,和函数)没有列在这里。只要知道xpath和jsonpath脚本之中的不同点就行了。

  • []在xpath表达式总是从前面的路径来操作数组,索引是从1开始。
  • 使用JOSNPath的[]操作符操作一个对象或者数组,索引是从0开始。

接下我们看jsonpath表示的例子。下面是一个简单的json数据结构代表一个书店(原始的xml文件是)

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
{ "store": {
    "book": [ 
      { "category": "reference",
        "author": "Nigel Rees",
        "title": "Sayings of the Century",
        "price": 8.95
      },
      { "category": "fiction",
        "author": "Evelyn Waugh",
        "title": "Sword of Honour",
        "price": 12.99
      },
      { "category": "fiction",
        "author": "Herman Melville",
        "title": "Moby Dick",
        "isbn": "0-553-21311-3",
        "price": 8.99
      },
      { "category": "fiction",
        "author": "J. R. R. Tolkien",
        "title": "The Lord of the Rings",
        "isbn": "0-395-19395-8",
        "price": 22.99
      }
    ],
    "bicycle": {
      "color": "red",
      "price": 19.95
    }
  }
}
XPath JSONPath 结果
/store/book/author $.store.book[*].author 书点所有书的作者
//author $..author 所有的作者
/store/* $.store.* store的所有元素。所有的bookst和bicycle
/store//price $.store..price store里面所有东西的price
//book[3] $..book[2] 第三个书
//book[last()] $..book[(@.length-1)] 最后一本书
//book[position()<3] $..book[0,1]$..book[:2] 前面的两本书。
//book[isbn] $..book[?(@.isbn)] 过滤出所有的包含isbn的书。
//book[price<10] $..book[?(@.price<10)] 过滤出价格低于10的书。
//* $..* 所有元素。

案例练习:1.淘票票 2.boos直聘 3.中华英才 4.汽车之家

BeautifulSoup

1.基本简介

1
2
3
4
5
6
7
1.BeautifulSoup简称
	bs4
2.什么是BeatifulSoup
	BeautifulSoup和lxml一样是一个html的解析器主要功能也是解析和提取数据
3.优缺点
	缺点效率没有lxml的效率高
	优点接口设计人性化使用方便

2.安装以及创建

1
2
3
4
5
6
7
8
9
10
1.安装
	pip install bs4
2.导入
	from bs4 import BeautifulSoup
3.创建对象
	服务器响应的文件生成对象
		soup = BeautifulSoup(response.read().decode(), 'lxml')
	本地文件生成对象
		soup = BeautifulSoup(open('1.html'), 'lxml')
		注意:默认打开文件的编码格式gbk所以需要指定打开编码格式

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
25
26
27
28
29
30
31
32
33
1.根据标签名查找节点
		soup.a 只能找到第一个a
			soup.a.name
			soup.a.attrs
2.函数
		(1).find(返回一个对象)
				find('a')只找到第一个a标签
        		find('a', title='名字')
				find('a', class_='名字')
		(2).find_all(返回一个列表)
				find_all('a') 查找到所有的a
				find_all(['a', 'span']) 返回所有的a和span
				find_all('a', limit=2) 只找前两个a
		(3).select(根据选择器得到节点对象)推荐
				1.element
					eg:p
				2..class
					eg:.firstname
				3.#id
					eg:#firstname
				4.属性选择器
					[attribute]
                    	eg:li = soup.select('li[class]')
                    [attribute=value]
						eg:li = soup.select('li[class="hengheng1"]')
                5.层级选择器
					element element
						div p
					element>element
						div>p
					element,element
						div,p
							eg:soup = soup.select('a,span')

4.节点信息

1
2
3
4
5
6
7
8
9
10
11
12
(1).获取节点内容适用于标签中嵌套标签的结构
		obj.string
		obj.get_text()推荐
(2).节点的属性
		tag.name 获取标签名
			eg:tag = find('li)
				print(tag.name)
		tag.attrs将属性值作为一个字典返回
(3).获取节点属性
		obj.attrs.get('title')【常用】
		obj.get('title')
		obj['title']

应用实例: 1.股票信息提取(http://quote.stockstar.com/) 2.中华英才网-旧版 3 .腾讯公司招聘需求抓取(https://hr.tencent.com/index.php)

Selenium

1.什么是selenium?

1
2
3
(1)Selenium是一个用于Web应用程序测试的工具。 
(2)Selenium 测试直接运行在浏览器中,就像真正的用户在操作一样。 
(3)支持通过各种driver(FirfoxDriver,IternetExplorerDriver,OperaDriver,ChromeDriver)驱动 真实浏览器完成测试。 (4)selenium也是支持无界面浏览器操作的。

2.为什么使用selenium?

1
 模拟浏览器功能,自动执行网页中的js代码,实现动态加载

3.如何安装selenium?

1
2
3
4
(1)操作谷歌浏览器驱动下载地址 http://chromedriver.storage.googleapis.com/index.html 
(2)谷歌驱动和谷歌浏览器版本之间的映射表 http://blog.csdn.net/huilan_same/article/details/51896672 
(3)查看谷歌浏览器版本 谷歌浏览器右上角‐‐>帮助‐‐>关于 
(4)pip install selenium

4.selenium的使用步骤?

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
 (1)导入:from selenium import webdriver 
 (2)创建谷歌浏览器操作对象: path = 谷歌浏览器驱动文件路径 browser = webdriver.Chrome(path) 
 (3)访问网址 url = 要访问的网址 browser.get(url)
 
元素定位:自动化要做的就是模拟鼠标和键盘来操作来操作这些元素,点击、输入等等。操作这些元素前首先
要找到它们,WebDriver提供很多定位元素的方法
方法:
1.find_element_by_id
	eg:button = browser.find_element_by_id('su')

2.find_elements_by_name
	eg:name = browser.find_element_by_name('wd')

3.find_elements_by_xpath
	eg:xpath1 = browser.find_elements_by_xpath('//input[@id="su"]')

4.find_elements_by_tag_name
	eg:names = browser.find_elements_by_tag_name('input')

5.find_elements_by_css_selector
	eg:my_input = browser.find_elements_by_css_selector('#kw')[0]
	
6.find_elements_by_link_text
	eg:browser.find_element_by_link_text("新闻")

1
2
3
4
5
6
7
4‐2:访问元素信息
获取元素属性
	.get_attribute('class')
获取元素文本
	.text
获取标签名
	.tag_name
1
2
3
4
5
6
7
8
9
10
4‐3:交互
	点击:click()
	输入:send_keys()
	后退操作:browser.back()
	前进操作:browser.forword()
	模拟JS滚动:
		js='document.documentElement.scrollTop=100000'
		browser.execute_script(js) 执行js代码
	获取网页代码:page_source
	退出:browser.quit()xxxxxxxxxx 

5.Chrome handless

Chrome-headless 模式, Google 针对 Chrome 浏览器 59版 新增加的一种模式,可以让你不打开UI界面的情况下 使用 Chrome 浏览器,所以运行效果与 Chrome 保持完美一致。

1
2
3
4
5
6
7
1.系统要求:
		Chrome
				Unix\Linux 系统需要 chrome >= 59
				Windows 系统需要 chrome >= 60
		Python3.6
		Selenium==3.4.*
		ChromeDriver==2.31
1
2
3
4
5
6
7
8
9
2.配置
from selenium.webdriver.chrome.options import Options
chrome_options = Options()
chrome_options.add_argument('‐‐headless')
chrome_options.add_argument('‐‐disable‐gpu')
path = r'C:\Program Files (x86)\Google\Chrome\Application\chrome.exe'
chrome_options.binary_location = path
browser = webdriver.Chrome(chrome_options=chrome_options)
browser.get('http://www.baidu.com/')
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
3.配置封装
		from selenium import webdriver
		#这个是浏览器自带的 不需要我们再做额外的操作
		from selenium.webdriver.chrome.options import Options
		def share_browser():
			#初始化
			chrome_options = Options()
			chrome_options.add_argument('‐‐headless')
			chrome_options.add_argument('‐‐disable‐gpu')
			#浏览器的安装路径 打开文件位置
			#这个路径是你谷歌浏览器的路径
			path = r'C:\Program Files (x86)\Google\Chrome\Application\chrome.exe'
			chrome_options.binary_location = path
            browser = webdriver.Chrome(chrome_options=chrome_options)
			return browser
封装调用
		from handless import share_browser
		browser = share_browser()
		browser.get('http://www.baidu.com/')
		browser.save_screenshot('handless1.png')

requests

1.基本使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
1.文档:
	官方文档
		http://cn.python‐requests.org/zh_CN/latest/
	快速上手
		http://cn.python‐requests.org/zh_CN/latest/user/quickstart.html
2.安装
	pip install requests
	
3.response的属性以及类型
	类型                          :models.Response
	r.text 						 : 获取网站源码
	r.encoding                   :访问或定制编码方式
	r.url                        :获取请求的url
	r.content                    :响应的字节类型
	r.status_code                :响应的状态码
	r.headers                    :响应的头信息

2.get请求

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
requests.get()
	eg:
		import requests
		url = 'http://www.baidu.com/s?'
	headers = {
			'User‐Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML,
				like Gecko) Chrome/65.0.3325.181 Safari/537.36'
	}
	data = {
		'wd':'北京'
	}
	response = requests.get(url,params=data,headers=headers)
定制参数
	参数使用params传递
	参数无需urlencode编码
	不需要请求对象的定制
	请求资源路径中?可加可不加

3.post请求

1
2
3
4
5
6
7
8
9
10
11
12
13
requests.post()
百度翻译:
	eg:
		import requests
		post_url = 'http://fanyi.baidu.com/sug'
		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'
		}
		data = {
			'kw': 'eye'
		}
		r = requests.post(url = post_url,headers=headers,data=data)
1
2
3
4
5
6
6:get和post区别?
	1: get请求的参数名字是params post请求的参数的名字是data
	2: 请求资源路径后面可以不加?
	3: 不需要手动编解码
	4: 不需要做请求对象的定制

4.代理

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
7:proxy定制
	在请求中设置proxies参数
	参数类型是一个字典类型
	eg:
		import requests
		url = 'http://www.baidu.com/s?'
		headers = {
			'user‐agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML,
		like Gecko) Chrome/65.0.3325.181 Safari/537.36'
		}
		data = {
			'wd':'ip'
		}
		proxy = {
			'http':'219.149.59.250:9797'
		}
		r = requests.get(url=url,params=data,headers=headers,proxies=proxy)
		with open('proxy.html','w',encoding='utf‐8') as fp:
		fp.write(r.text)

5.cookie定制

1
2
3
4
5
6
7
8:cookie定制
	应用案例:
		(1)古诗文网(需要验证)
		(2)云打码平台
			用户登陆 actionuser action
			开发者登陆 actioncode action

scrapy

1
2
3
4
(1)scrapy是什么?
		Scrapy是一个为了爬取网站数据,提取结构性数据而编写的应用框架。 可以应用在包括数据挖掘,信息处理
或存储历史数据等一系列的程序中。

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
(2)安装scrapy:
			pip install scrapy
	安装过程中出错:
			如果安装有错误!!!!
			pip install Scrapy
			building 'twisted.test.raiser' extension
			error: Microsoft Visual C++ 14.0 is required. Get it with "Microsoft Visual C++
			Build Tools": http://landinghub.visualstudio.com/visual‐cpp‐build‐tools
	解决方案:
			http://www.lfd.uci.edu/~gohlke/pythonlibs/#twisted
			下载twisted对应版本的whl文件(如我的Twisted‐17.5.0‐cp36‐cp36m‐win_amd64.whl),cp后面是
			python版本,amd64代表64位,运行命令:
			pip install C:\Users\...\Twisted‐17.5.0‐cp36‐cp36m‐win_amd64.whl
			pip install Scrapy
	如果再报错
			python ‐m pip install ‐‐upgrade pip
	如果再报错 win32
	解决方法:
			pip install pypiwin32
    再报错:使用anaconda
	使用步骤:
		打开anaconda
		点击environments
		点击not installed
		输入scrapy
		apply
		在pycharm中选择anaconda的环境

1.scrapy项目的创建以及运行

1
2
1.创建scrapy项目:
	终端输入 scrapy startproject 项目名称
1
2
3
4
5
6
7
8
9
10
2.项目组成:
	spiders
		__init__.py
		自定义的爬虫文件.py ‐‐‐》由我们自己创建,是实现爬虫核心功能的文件
	__init__.py
	items.py ‐‐‐》定义数据结构的地方,是一个继承自scrapy.Item的类
	middlewares.py ‐‐‐》中间件 代理
	pipelines.py ‐‐‐》管道文件,里面只有一个类,用于处理下载数据的后续处理默认是300优先级,值越小优先级越高(1‐1000)
	settings.py ‐‐‐》配置文件 比如:是否遵守robots协议,User‐Agent定义等

1
2
3
4
5
6
7
8
9
10
11
12
13
14
3.创建爬虫文件:
			(1)跳转到spiders文件夹 cd 目录名字/目录名字/spiders
			(2)scrapy genspider 爬虫名字 网页的域名
爬虫文件的基本组成:
			继承scrapy.Spider类
					name = 'baidu' ‐‐‐》 运行爬虫文件时使用的名字
					allowed_domains ‐‐‐》 爬虫允许的域名,在爬取的时候,如果不是此域名之下的url,会被过滤掉
					start_urls ‐‐‐》 声明了爬虫的起始地址,可以写多个url,一般是一个
					parse(self, response) ‐‐‐》解析数据的回调函数
								response.text ‐‐‐》响应的是字符串
								response.body ‐‐‐》响应的是二进制文件
								response.xpath()‐》xpath方法的返回值类型是selector列表
								extract() ‐‐‐》提取的是selector对象的是data
								extract_first() ‐‐‐》提取的是selector列表中的第一个数据
1
2
3
4.运行爬虫文件:
	scrapy crawl 爬虫名称
	注意:应在spiders文件夹内执行

3.scrapy架构组成

1
2
3
4
5
6
7
8
9
10
11
12
13
	(1)引擎 ‐‐‐》自动运行,无需关注,会自动组织所有的请求对象,分发给下载器
	(2)下载器 ‐‐‐》从引擎处获取到请求对象后,请求数据
	(3)spiders ‐‐‐》Spider类定义了如何爬取某个(或某些)网站。包括了爬取的动作(例如:是否跟进链接)以及如何从网页的内容中提取结构化数据(爬取item)。 换句话说,Spider就是您定义爬取的动作及分析某个网页(或者是有些网页)的地方。
	(4)调度器 ‐‐‐》有自己的调度规则,无需关注
	(5)管道(Item pipeline) ‐‐‐》最终处理数据的管道,会预留接口供我们处理数据
当Item在Spider中被收集之后,它将会被传递到Item Pipeline,一些组件会按照一定的顺序执行对Item的处理。
每个item pipeline组件(有时称之为“Item Pipeline”)是实现了简单方法的Python类。他们接收到Item并通过它执行
一些行为,同时也决定此Item是否继续通过pipeline,或是被丢弃而不再进行处理。
		以下是item pipeline的一些典型应用:
				1. 清理HTML数据
				2. 验证爬取的数据(检查item包含某些字段)
				3. 查重(并丢弃)
				4. 将爬取结果保存到数据库中

4.scrapy工作原理

image-20230410151719563

2.scrapy shell

1
2
3
4
5
1.什么是scrapy shell?
	Scrapy终端,是一个交互终端,供您在未启动spider的情况下尝试及调试您的爬取代码。 其本意是用来测试提取数据的代码,不过您可以将其作为正常的Python终端,在上面测试任何的Python代码。
	该终端是用来测试XPath或CSS表达式,查看他们的工作方式及从爬取的网页中提取的数据。 在编写您的spider时,该终端提供了交互性测试您的表达式代码的功能,免去了每次修改后运行spider的麻烦。
	一旦熟悉了Scrapy终端后,您会发现其在开发和调试spider时发挥的巨大作用。

1
2
3
4
2.安装ipython
	安装:pip install ipython
	简介:如果您安装了 IPython ,Scrapy终端将使用 IPython (替代标准Python终端)。 IPython 终端与其他相
比更为强大,提供智能的自动补全,高亮输出,及其他特性。
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
3.应用: (1)scrapy shell www.baidu.com
		(2)scrapy shell http://www.baidu.com
		 (3) scrapy shell "http://www.baidu.com"
		 (4) scrapy shell "www.baidu.com"
  语法:
  		(1)response对象:
					response.body
					response.text
					response.url
					response.status
		(2)response的解析:
					response.xpath() (常用)
							使用xpath路径查询特定元素,返回一个selector列表对象
					response.css()
							使用css_selector查询元素,返回一个selector列表对象
							获取内容 :response.css('#su::text').extract_first()
							获取属性 :response.css('#su::attr(“value”)').extract_first()
		(3)selector对象(通过xpath方法调用返回的是seletor列表)
					extract()
								提取selector对象的值
								如果提取不到值 那么会报错
								使用xpath请求到的对象是一个selector对象,需要进一步使用extract()方法拆包,转换为									unicode字符串
					extract_first()
								提取seletor列表中的第一个值
								如果提取不到值 会返回一个空值
								返回第一个解析到的值,如果列表为空,此种方法也不会报错,会返回一个空值
					xpath()
					css()
								注意:每一个selector对象可以再次的去使用xpath或者css方法

3.yield

  1. 带有 yield 的函数不再是一个普通函数,而是一个生成器generator,可用于迭代
  2. yield 是一个类似 return 的关键字,迭代一次遇到yield时就返回yield后面(右边)的值。重点是:下一次迭代 时,从上一次迭代遇到的yield后面的代码(下一行)开始执行

  3. 简要理解:yield就是 return 返回一个值,并且记住这个返回的位置,下次迭代就从这个位置后(下一行)开始

4.pymysql的使用步骤

1
2
3
4
1.pip install pymysql
2.pymysql.connect(host,port,user,password,db,charset)
3.conn.cursor()
4.cursor.execute()

5.CrawlSpider

1
2
3
4
1.继承自scrapy.Spider
2.独门秘笈
	CrawlSpider可以定义规则,再解析html内容的时候,可以根据链接规则提取出指定的链接,然后再向这些链接发送请求
	所以,如果有需要跟进链接的需求,意思就是爬取了网页之后,需要提取链接再次爬取,使用CrawlSpider是非常合适的
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
3.提取链接
	链接提取器,在这里就可以写规则提取指定链接
scrapy.linkextractors.LinkExtractor(
	allow = (), 			# 正则表达式 提取符合正则的链接
	deny = (), 				# (不用)正则表达式 不提取符合正则的链接
	allow_domains = (), 	# (不用)允许的域名
	deny_domains = (),  	# (不用)不允许的域名
	restrict_xpaths = (), 	# xpath,提取符合xpath规则的链接
	restrict_css = () 		# 提取符合选择器规则的链接)
4.模拟使用
		正则用法:links1 = LinkExtractor(allow=r'list_23_\d+\.html')
		xpath用法:links2 = LinkExtractor(restrict_xpaths=r'//div[@class="x"]')
		css用法:links3 = LinkExtractor(restrict_css='.x')
5.提取连接
		link.extract_links(response)
1
2
3
6.注意事项
	【注1】callback只能写函数名字符串, callback='parse_item'
	【注2】在基本的spider中,如果重新发送请求,那里的callback写的是 callback=self.parse_item 【注‐‐稍后看】follow=true 是否跟进 就是按照提取连接规则进行提取

运行原理:

image-20230410152841465

6.CrawlSpider案例

需求:读书网数据入库

1
2
3
4
5
6
7
8
9
10
1.创建项目:scrapy startproject dushuproject
2.跳转到spiders路径 cd\dushuproject\dushuproject\spiders
3.创建爬虫类:scrapy genspider ‐t crawl read www.dushu.com
4.items
5.spiders
6.settings
7.pipelines
		数据保存到本地
		数据保存到mysql数据库

7.数据入库

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
1settings配置参数
			DB_HOST = '192.168.231.128'
			DB_PORT = 3306
			DB_USER = 'root'
			DB_PASSWORD = '1234'
			DB_NAME = 'test'
			DB_CHARSET = 'utf8'
2管道配置
			from scrapy.utils.project import get_project_settings
			import pymysql
			class MysqlPipeline(object):
			#__init__方法和open_spider的作用是一样的
			#init是获取settings中的连接参数
				def __init__(self):
					settings = get_project_settings()
					self.host = settings['DB_HOST']
					self.port = settings['DB_PORT']
					self.user = settings['DB_USER']
					self.pwd = settings['DB_PWD']
					self.name = settings['DB_NAME']
					self.charset = settings['DB_CHARSET']
					self.connect()
			# 连接数据库并且获取cursor对象
				def connect(self):
					self.conn = pymysql.connect(host=self.host,port=self.port,user=self.user,
												password=self.pwd,db=self.name,charset=self.charset)
					self.cursor = self.conn.cursor()
				def process_item(self, item, spider):
					sql = 'insert into book(image_url, book_name, author, info) values("%s","%s", "%s", "%s")' % (item['image_url'], item['book_name'], item['author'], item['info'])
					sql = 'insert into book(image_url,book_name,author,info) values
("{}","{}","{}","{}")'.format(item['image_url'], item['book_name'], item['author'],
item['info'])
# 执行sql语句
					self.cursor.execute(sql)
					self.conn.commit()
					return item
				def close_spider(self, spider):
					self.conn.close()
					self.cursor.close()

8.日志信息和日志等级

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
(1)日志级别:
		CRITICAL:严重错误
		ERROR: 一般错误
		WARNING: 警告
		INFO: 一般信息
		DEBUG: 调试信息
		默认的日志等级是DEBUG
		只要出现了DEBUG或者DEBUG以上等级的日志
		那么这些日志将会打印
(2)settings.py文件设置:
		默认的级别为DEBUG,会显示上面所有的信息
		在配置文件中 settings.py
		LOG_FILE : 将屏幕显示的信息全部记录到文件中,屏幕不再显示,注意文件后缀一定是.log
		LOG_LEVEL : 设置日志显示的等级,就是显示哪些,不显示哪些

9.scrapy的post请求

1
2
3
4
5
6
7
8
(1)重写start_requests方法:
		def start_requests(self)
(2) start_requests的返回值:
		scrapy.FormRequest(url=url, headers=headers, callback=self.parse_item, formdata=data)
				url: 要发送的post地址
				headers:可以定制头信息
				callback: 回调函数
				formdata: post所携带的数据,这是一个字典	

10.代理

1
2
3
4
5
6
7
8
(1)到settings.py中,打开一个选项
	DOWNLOADER_MIDDLEWARES = {
		'postproject.middlewares.Proxy': 543,
	}
(2)到middlewares.py中写代码
	def process_request(self, request, spider):
		request.meta['proxy'] = 'https://113.68.202.10:9999'
		return None