爬虫笔记(一)
1 字符串和二进制之间的相互转换
字符串转化为二进制:encode() 默认为utf8,若为gbk需要注明
二进制转化为字符串:decode() 默认为utf8,若为gbk需要注明
2 url规范:
只能由特定字符组成,字母、数字、下划线,如果出现其他字符(中文、空格等)就要对其进行编码
3 urllib.response
read() 读取相应的内容,内容是字节类型
geturl() 读取请求的url
getheaders() 读取头部信息,列表中元素有元组
getcode() 获取状态码
readlines() 按行读取,返回列表,内容为字节类型
4 urllib.parse
quote() url编码函数,将中文进行转化为%XXX
unquote() url解码函数,将%XXX转化为指定字符
urlencode() 给一个字典,将字典拼接为query_string,并且实现了编码
5 UA(user agent)用户代理
是Http协议中的一部分,属于头域的组成部分,User Agent也简称UA。
它是一个特殊字符串头,是一种向访问网站提供你所使用的浏览器类型及版本、操作系统及版本、浏览器内核、等信息的标识。
通过这个标识,用户所访问的网站可以显示不同的排版从而为用户提供更好的体验或者进行信息统计;
例如用手机访问谷歌和电脑访问是不一样的,这些是谷歌根据访问者的UA来判断的。UA可以进行伪装。
6 构建请求头部信息(反爬虫第一步)
伪装自己的UA.让服务器认为是浏览器在上网
构建请求对象:urllib.request.Request(参数需要提供url和伪装UA后的请求)
7 Ajax(Asynchronous Javascript And XML)
一种创建交互式网页应用的网页开发技术,用于创建快速动态网页的技术
8 URLError\HTTPError异常处理 try-except
URLError:
(1):没有网
(2):服务器连接失败
(3):找不到指定的服务器
HTTPError:
是URLError的子类
注:两个同时捕获的时候,需要将子类错误放在前面
9 Handler处理器、自定义Opener
urlopen() 给定一个url,发送请求,获取响应
Request() 定制请求头,创建请求对象
高级功能 使用代理,使用cookie
10 代理:
生活中的代理:微商、代驾
程序中的代理
正向代理 顺着请求的方向去进行的代理,替客户端去请求目标服务器地址(爬虫关注)获取数据
反向代理 代理目标服务器提供数据
配置:
浏览器配置:设置-高级-系统-打开代理设置-连接-局域网设置-代理服务器--输入ip和端口号
代码配置:handler = urllib.request.ProxyHandler({'http': '123.163.97.59:9999'})
opener = urllib.request.build_opener(handler)
后续都使用opener.open方法去发送请求
11 cookie
cookie是什么?
http协议,无状态
网站登录时候的问题,用来记录用户身份的
模拟登陆
12 cookie登录
# 创建一个cookiejar对象
cj = http.cookiejar.CookieJar()
# 通过cookiejar创建一个handler
handler = urllib.request.HTTPCookieProcessor(cj)
# 根据handler创建一个opener
opener = urllib.request.build_opener(handler)
再往下所有操作都是用opener.open方法去发送请求,因为这里带着cookie过去了
13 正则表达式解析
为什么引入正则表达式?
用来匹配一类具有相同规则的字符串(包含正则匹配和正则替换)
规则
单字符:
. :除换行以外所有字符
[]:[a-w]匹配集合中任意一个字符
\d:数字[0-9]
\D:非数字
\w:数字、字母、下划线、中文
\W:非w
\S:非空白字符
\s:所有的空白字符
数量修饰:
*:任意多次 >=0
+: 至少一次 >=1
?: 可有可无 0次或1次
{m}:固定m次
{m,n}:m-n次
边界:
\b
\B
$:以某某结尾
^:以某某开头
分组:
() 视为一个整体(ab){3}
() 子模式\组模式 \1 \2
贪婪模式
.*? .+?(加个?反贪婪)
re.I: 忽略大小写
re,M:多行匹配
re.S:单行匹配
match\search\findall:从开头开始\从任意位置开始\匹配所有
re.sub(正则表达式,替换内容,字符串)
http://www.yikexun.cn/
需求:
爬取指定页面的标题和内容
保存到html文件中,标题用h1,内容使用p即可
14 bs4
BeautifulSoup
需要将pip源设置为国内源,阿里源、豆瓣源、网易源等
windows
(1)打开文件资源管理器
(2)地址栏上面输入%appdata%
(3)在这里面新建一个文件夹 pip
(4)在文件夹里面新建一个文件夹 pip.ini
写如下内容
[global]
timeout = 6000
index-url = https://mirrors.aliyun.com/pypi/simple/
trusted-host = mirrors.aliyun.com
依赖库bs4,lxml
简单使用:
说明:选择器,jquery
from bs4 import BeautifulSoup
使用方式:可以将一个html文档,转化为指定的对象,然后通过对象的方法或者属性去查找指定的内容
(1)转化为本地文件:
soup = BeautifulSoup(open('本地文件'),'lxml')
(2)转化为网络文件:
soup = BeautifulSoup('字符串类型或者字节类型','lxml')
(1)根据标签名查找
soup.a 只能找到第一个符合要求的标签(a代表连接)
(2)获取属性
soup.a.attrs 获取所有属性和值,返回一个字典
soup.a.attrs['href'] 获取href属性 简写为soup.a['href']
(3)获取内容
soup.a.text
soup.a.string
soup.a.get_text
若标签里还有标签,string结果为none,其他两个可以获取内容
(4)find
soup.find('a') 找到第一个符合条件的a
soup.find('a', title='qing')
soup.find('a', id='feng')
soup.find('a', class_='du')(class为关键字,需加下划线)
find方法不仅soup可以调用,普通的div对象也能调用,会去指定的div里面去查找符合要求的节点
find找到第一个对象
(5)find_all
soup.find_all('a')
soup.find_all(['a', 'b'])
soup.find_all('a', limit=2) 限制前两个
(6)select(得到的是一个列表)
根据选择器选择指定的内容、
常见的选择器:标签选择器、类选择器、id选择器、组合选择器、层级选择器、伪类选择器、属性选择器
标签选择器 a
类选择器 .dudu
id选择器 #lala
组合选择器 a, .dudu, #lala, .meme
层级选择器 div .dudu #lala .meme .xixi 下面好多级
伪类选择器 div > p > a >.lala 只能是下面一级
属性选择器 input[name='lala']
select选择器返回的永远是列表,需要通过下标提取指定的对象,然后获取属性和节点
该方法也可以通过普通对象调用,找到都是这个对象下面符合要求的所有节点
15 xpath
pip install lxml
xml 可扩展标记语言,是用来存储和传输数据使用的。
和html的不同的主要有两点:
(1)html用来显示数据,xml是用来传输数据
(2)html标签是固定的,xml标签是自定义的
xpath用来在xml中查找指定的元素,它是一种路径表达式
//: 不考虑位置的查找
./: 从当前节点开始往下查找
../: 从当前节点的父节点查找
@: 选择属性
实例:
/bookstore/book 选择根节点bookstore下面所有直接子节点book
//book 选取所有book
bookstore//book 查找bookstores下面所有的book
/bookstore/book[1] bookstore下面的第一个book
安装xpath插件
启动和关闭插件 ctrl + shift + x
属性定位
//input[@id="kw"]
//input[@class="btn self-btn bg s_btn"]
层级定位
索引定位(索引从1开始)
//div[@id="head"]/div/div[2]/a[@class="toindex"]
//div//a[@class="toindex"] 双斜杠代表下面所有的a节点,不管位置
逻辑运算
//input[@name="wd" and @class="s_ipt"]
模糊匹配
contains
//input[contains(@class, "s_i")] 所有的input,有class属性,并且属性中带有s_i的节点
//input[contains(text(), "测试")]
starts-with
//input[starts-with(@class, "s_i")] 所有的input,有class属性,并且属性中以s开头的节点
取文本
//div[@id="u_sp"]/a[5]/text() 获取节点内容
//div[@id="u_sp"]//text() 获取节点里面不带标签的所有内容
直接将所有内容拼接起来返回给你
ret = tree.xpath('//div[@class="song"]')
string = ret[0].xpath('string(.)')
print(string.replace('\n', '').replace('\t', ''))
取属性
//div[@id="u_sp"]/a[5]/@href
代码中使用xpath
from lxml import etree
两种方式使用:将html文档变成一个对象,然后调用对象的方法去查找指定的节点
(1)本地文件
tree = etree.parse(文件名)
(2)网络文件
tree = etree.HTML(网页字符串)