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 ) 关闭浏览器重新打开
( 9 ) ctrl + 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 [ starts ‐ with ( @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工作原理
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
带有 yield 的函数不再是一个普通函数,而是一个生成器generator,可用于迭代
yield 是一个类似 return 的关键字,迭代一次遇到yield时就返回yield后面(右边)的值。重点是:下一次迭代 时,从上一次迭代遇到的yield后面的代码(下一行)开始执行
简要理解: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 是否跟进 就是按照提取连接规则进行提取
运行原理:
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
( 1 ) settings配置参数 :
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