4、urllib库
模拟浏览器发送请求的库,Python自带
Python2: urllib urllib2
Python3: urllib.request urllib.parse
字符串==》字节类型之间的转化
encode() 字符串==》字节类型
如果小括号里面不写参数,默认是utf8
如果写,就写gbk
decode() 字节类型==》字符串
如果不写 默认utf8
如果写,就写gbk
urllib.request
urlopen(url)
urlretrieve(url,image_path)
urllib.parse
quote(url) url编码函数,将中文进行转化为%xxx;注意,发请求的url不能包含中文和特殊字符,所以有特殊字符和中文则需要用此函数编码
unquite(url) url解密函数,将%xxx转化成相应字符串
urlencode(url) 将一个字典拼接为query_string,并且实现了编码的功能
response
read() 读取相应内容,内容是字节类型
geturl() 获取请求的url
getheaders() 获取头部信息,列表里面有元组
getcode() 获取状态码
readlines() 按行读取,法规列表,都是字节类型
5、get方式
构建请求头部信息(这是反爬的第一步)
a)伪装自己的UA,让服务端认为你是浏览器在上网
b)构建请求对象 urllib.request.Request(url=url,headers=headers)
c)ssl._create_default_https_context = ssl._create_unverified_context # 取消ssl验证
6、post方式
1.【注】表单数据的处理
urllib.parse.urlencode(form_data).encode()
fidder抓包,一个本上面有个箭头,代表就是post请求
' Accept-Encoding': 'gzip, deflate, br', # 此句不需要加
7、ajax
8、URLErrorHTTPError
这两个类都在urllib.error模块中
NameError TypeError FileNotFound 异常
异常处理,结构 try-except
URLError:
(1)没有网
(2)服务器连接失败(域名不存在)
(3)找不到指定的服务器
HTTPError:
是URLError的子类
【注】两个同时捕获的时候,需要将HTTPError写到上面,HTTPError写在下面
9、Handler处理器、自定义Opener
a)urlopen() 给个url,发送请求,获取响应
b)Request() 定制请求头,创建请求对象
10、高级功能:使用代理,cookie
基本用法:
a)代理
1、代理是什么?
2、生活中的代理:微商、代练
3、程序中的代理:
正向代理:代理客户端获取数据
反向代理:代理服务端提供数据
4、配置:
浏览器配置
代码代理
handler = urllib.request.ProxyHandler({'http':'116.209.58.148:9999'})
opener = urllib.request.build_opener(handler)
后续都使用opener.open方法去发送请求即可
b)cookie
1、cookie是什么?
2、http协议,无状态
3、登录网站时候的问题,用来记录用户身份的
模拟登录:
# 创建一个cookiejar对象 cj = http.cookiejar.CookieJar() # 通过cookiejar创建一个handlder handler = urllib.request.HTTPCookieProcessor(cj) # 通过handler 创建一个opner opener = urllib.request.build_opener(handler)
再往下所有的操作都是用opener.open方法发送请求,因为这里面带着cookie过去了
11、正则表达式解析:
a)单字符:
. : 除换行符以外所有字符
[] : [aoe] [a-w] 匹配集合中的任意一个字符
d : 非数字
w : 数字、字母、下划线、中文
W : 非w
s : 所有的空白字符
S : 非空白
b)数量修饰:
* :任意多次 >=0
+ : 至少一次 >=1
? : 可有可无 0次或者1次
{m} : 固定m次
{m,} : 至少m次
{m,n} : m-n次
c)边界:
B
$ : 以某某结尾
^ : 以某某开头
d)分组:
(ab){3}
(){4} 视为一个整体
() 子模式组模式 1 2
e)贪婪模式:
.*? .+? # 加?取消贪婪
re.I : 忽略大小写
re.M : 多行匹配
re.S : 单行匹配(多行变单行)
matchsearchfindall
re.sub(正则表达式,替换内容,字符粗)
12、bs4(BeautifulSoup)
a)需要将pip源设置为国内源
Windows:
(1)打开文件资源管理器
(2)地址栏上面输入%appdata%
(3)在这里面 新建一个文件夹pip
(4)在pip文件夹里面新建一个文件叫做 pip.ini,内容如下即可
[global] timeout = 6000 index-url = https://mirrors,aliyun.com/pypi/simple/ trusted-host = mirrors.aliyun.com
Linux:
(1)cd ~
(2)mkdir ~/.pip
(3)vi ~/.pip/pip.conf
(4)编辑内容,和windows一样
(2)需要安装:pip install bs4
b)bs4在使用时候需要一个第三方库lxml(pip install lxml)
c)简单使用:
1、说明:选择器
2、导入:from bs4 import BeautifulSoup
3、使用方式:可以将一个html文档,转换成指定的对象,然后通过对象的方法或者属性去查找指定的内容
4、转化本地文件:
soup = BeautifulSoup(open('本地文件'),'lxml')
5、转化网络文件:
soup = BeautifulSoup('字符串类型/字节类型','lxml')
6、使用方法:
1)根据标签名查找
soup.a 只能找到第一个符合要求的标签
2)获取属性
soup.a.attrs 获取所以的属性和值,返回一个字典
soup.a['title'],soup.a.attrs['title'] 两个等价
3)获取内容
soup.a.text:都能获取
soup.a.string:只能是文本,如果标签里有标签的话,获取None
soup.a.get_text():都能获取
4)find(找到的都是第一个符合要求的节点)
soup.find('a') 找到第一个符合要求的a标签
soup.find('a',title='qing')
soup.find('a',class_='aaa') # 注意class是关键字要用class_
soup.find('div',class_='song').find('p',class_='li') 可以连缀查找
5)find_all (返回所有符合要求的节点)
soup.find_all('a','b') # 支持同时查找多标签
soup.find_all('a',limit=2) # 支持查找数据量
6)select
根据选择器选择指定的内容
常见选择器:标签选择器、类选择器、id选择器、组合选择器、层级选择器、伪类选择器、属性选择器
select 选择器返回永远是列表,该方法也可以通过普通对象调用
13、xpath
a)什么是xpath?
xml是用来存储和传输数据
b)和html的不同的两点:
1)html用来显示数据,xml是用来传输数据
2)html标签是固定的,xml标签是自定义的
c)xpath用来在xml中查找指定的元素,它是一种路径表达式
常用的路径表达式:
// : 从不考虑位置的查找
./ : 从当前节点开始往下查找
@ : 选取属性
实例:
/bookstore/book 选取根节点bookstore下面所有直接子节点book //book 选取所有book bookstore//book 查找bookstore下面所有的book /bookstore/book[1] bookstore里面的第一个book /bookstore/book[last()] bookstore里面的最后一个book /bookstore/book[position()<3] 选取bookstore里面的前两个book //title[@lang] 选取所有拥有lang属性的tittle //title[@lang='eng'] 选取所有拥有lang属性值为eng的title
* :匹配任何元素节点
d)安装xpath插件
1、将xpath插件拖动到谷歌浏览器扩展程序中
2、启动和关闭插件
3、ctrl + shift + x
e)属性定位
//input[@id="wk"]
//input[@class="bg s_btn"] # 多个class是个整体,不可拆分查找
f)层级定位
h)索引定位
//div[@id="head"]/div/div[2]/a[@class="toindex"]
【注】索引从1开始
//div[@id="head"]//a[@class="toindex"]
【注】双斜杠代表下面所有的a节点,不管位置
i)逻辑运算
//input[@class="s_ipt" and @name="wd"]
j)模糊匹配【】
1、contains
//input[contains(@class,"s_i")]
所有的input,有class属性,并且class中包含s_i
//input[contains(text(),"爱")]
2、starts-with
//input[contains(@class,"s")]
所有的input,有class属性,并且class中必须以s开头
k)取文本
//div[@id="u1"]/a[5]/text() //div[@id="u1"]//text() 获取节点里面不带标签的所有内容 string = ret[0].xpath('string(.)') # 直接将内容拼接起来返回 print(string.replace(' ','').replace(' ','').replace(' ',''))
m)取属性
//div[@id="u1"]/a[5]/@href
代码里使用xpath
导入库:from lxml import etree
两种方式使用:将html文档变成一个对象,然后调用对象的方法查找指定的节点
1、本地文件
tree = etree.parse(文件名,etree.HTMLParser(encoding="utf-8"))
2、网络文件
tree = etree.HTML(网页字符串)
3、换行问题:
a)存储的时候显示的
是有效的
b)在读取过来单独使用的时候换行符生效'
14、图片加载问题
a)懒加载技术:用到的时候加载
实现方式:
<img src2="图片路径"> 加载时变为下面格式 <img src="图片路径">
15、jsonpath
jsonpath:用来解析json数据使用的
python处理json格式用到的函数
使用:import json
json.dumps():将字典或者列表转化为json格式的字符串
json.loads():将json字符串转化为Python对象
json.dump():将字典或者列表转化为json格式字符串并且写入到文件中
json.load():从文件中读取json格式字符串,转换为Python对象
安装:
pip install lxml
pip install jsonpath
用法:
jsonpath用一个抽象的名字$来表示最外层对象。
xpath的表达式:/store/book[1]/title
jsonpath的表达式:x.store.book[0].title
或 x['store']['book'][0]['title']
xpath 和 jsonpath对比:
/ $ 表示跟元素
. @ 当前元素
/ . 子元素
// .. 任意位置查找
* * 通配符
[] ?() 过滤
xpath 索引下标从1开始
jsonpath 索引下标从0开始
16、selenium和PhantomJS
1、selenium是什么?
python的第三方库,对外提供接口可以操作你的浏览器,然后让浏览器自动化的操作
2、使用selenium
安装:pip install selenium
操作谷歌浏览器,首先必须有谷歌浏览器的一个驱动
谷歌驱动下载地址
http://chromedriver.storage.googleapis.com/index.html
谷歌驱动和谷歌浏览器版本关系映射表
https://blog.csdn.net/huilan_same/article/details/51896672
3、代码操作
from selenium import webdriver browser = webdriver.Chrome(path) browser.get()
4、使用下面方法,找到指定的元素进行操作即可
find_element_by_id 根据id找节点
find_element_by_name 根据name找
find_element_by_xpath 根据xpath查找
find_element_by_tag_name 根据标签名找
find_element_by_class_name 根据class名字查找
find_element_by_css_selector 根据选择器查找
find_element_by_link_text 根据链接内容查找
getsend_keysclick
5、PhantomJS
a、是什么?是一款浏览器,无界面浏览器
b、selenium+phantomjs 就是爬虫终极解决方案
1、下拉滚动条到底部
2、豆瓣电影下拉
3、图片懒加载
4、获取网页的代码:browser.page_source
17、Headless Chrome
1、无头谷歌浏览器,无界面谷歌浏览器
2、因为phantomjs现在都不维护了
3、mac、linux,版本号59+以上,才支持这种模式
4、windows,要求版本号的60+以上,才支持这种模式
5、使用
from selenium.webdriver.chrome.options import Options chrome_options = Options() chrome_options.add_argument('--headless') chrome_options.add_argument('--disable-gpu')
18、requests
安装:pip install requests
官方文档:
http://cn.python-requests.org/zh_CN/latest/
用来做什么?
和urllib是同一个为位置的,是对urllib的封装,底层是urllib3
get请求
定制头部
data:是一个原生字典
requests.get(url,headers=headers,params=data)
响应对象
r.text 字符串形式查看响应
r.content 字节类型查看响应
r.encoding 查看或者设置编码类型
r.status_code 查看状态码
r.headers 查看响应头部
r.url 查看所请求的url
post请求
必应翻译
formdata:是一个原生字典
r = requests.post(url,headers=headers,data=formdata)
ajax、get、post
和上面一样
代理
r = requests.get(url=url,headers=headers,params=data,proxies=proxies)
cookie
s = requests.Session()
r = s.get(url=url,headers=headers,params=data,proxies=proxies)
chinaunix
登录思路:先get,再post,再get
19、验证码
a)tesseract简介
光学识别,只能识别简单的验证码
代码测试:pip install pytesseract pillow
b)打码平台
打码兔、云打码
23、线程回顾
a、引入
多任务,多个任务同时进行,多进程,多线程
多进程:sublime、录屏、vnc服务器
多线程:word(包括编辑,查看等线程同时执行)
b、创建线程Thread
1、面向过程:
tsing = threading.Thread(target=sing,name='sing',args=(a, ))
target:线程启动之后要执行的函数
name:线程的名字
获取线程名字:threading.current_thread().name
# 启动线程
tsing.start()
# 让主线程等待子线程结束之后再结束
tsing.join()
# 这里是主线程
print('这里是主线程')
2、面向对象
定义一个类,继承自threading.Thread,重写一个方法run方法,
需要主线程名字、传递参数,重写构造方法,在重写构造方法的时候,
一定要注意手动调用父类的构造方法。
3、线程同步
线程之间共享全局变量,很容易发生数据混乱问题,
这个时候要使用线程锁,抢,谁抢到,谁上锁之后,谁就先用
4、创建锁
suo = threading.lock()
上锁
suo.acquire()
释放锁
suo.release()
5、队列(queue)
a)下载线程
//解析线程,通过队列进行交互
q = Queue(5)
q.put('xxx') 如果队满,程序卡在这里等待
q.put('xxx',False) 如果队满,程序直接报错
q.put('xxx',True,3) 如果队列满,程序等待3s再报错
b)获取数据
print(q.get()) 如果队列为空,程序卡在这里等待
print(q.get(False)) 如果队列为空,程序直接报错
print(q.get(True,3)) 如果队列为空,程序等待3s报错
c)q.empty() 判断队列是否为空
d)q.full 判断队列是否已满
e)q.qsize 判断队列长度
24、多线程爬虫
分析:
两类线程:下载(3)、解析线程(3)
内容队列:下载线程往队列中put数据,解析线程从队列get数据
url队列:下载线程从url队列get数据
写数据:上锁