学习目标:
python爬虫部分的学习
学习内容:
mooc北京理工大学·Python网络爬虫与信息提取
对Scrapy内核依然一知半解,但mooc内容已经学完整理
后续将对Scrapy继续进行学习
将后续的Numpy库暂缓
个人认为这组课没python语言程序设计讲得好,很多点都没有讲清楚,需要直接查资料填补
学习产出:
python爬虫与信息提取
Requests库
机理
向服务器端发送请求时,服务器为本次请求创建request对象,Request对象中封装了客户端发送过来的所有的请求数据。
r=requests.get(url)
requests.get()函数构造了一个向服务器请求资源的Request对象 返回一个包含服务器资源的Response对象指向r
七个主方法
.request(method,url,**kwargs)
构造一个请求,为各方发的基础方法
method对应六个方法
kwargs: params 字典或字节序列,作为参数增加到url中 data 字典,字节序列或文件对象,作为Request的内容提交 json JSON格式的数据,作为Request内容部分提交 headers 字典,HTTP定制头,修改头文件 cookise 字典或CookieJar auth 元组,支持HTTP认证功能 files 字典类型,传输文件 timeou 设置超时时间,秒为单位 proxies 字典类型,设定访问代理服务器,可以增加登录验证 allow_redirects True/False,默认为T,重定向开关 streamTrue/False,默认为T,获取内容立即下载开关 verifyTrue/False,默认为T,认证SSL证书开关 cert 本地SSL证书路径
kv={} r=r.r('GET','url', params =kv) r.url=url+?+eval(kv)
r=r.r('POST','url', data =kv) 将kv存储到url对应部分
jion同理
hd={'user-agent':'Chrome/10'} r=r.r('POST','url', headers =hd 改变请求网站时的request对象的头文件对应内容
fs={'file':open('data.xls','rb') r=r.r('POST','url', files =fs 向url提交文件
psx={'http':'http://user:pass@10.10.10.1:1234''https':'https://10.10.10.1:4321'} r=r.r('GET','url', proxies =pxs) 增加http和https代理
.get(url,params=None,**kwargs)
获取HTML网页的主要方法,对应HTTP的GET
params为url中的额外参数,字典或字节流格式,可选
.head(url,**kwargs)
获取HTML网页头信息的方法,对应HTTP的HEAD
.post(url,data=None,json=None,**kwargs)
向HTML网页提交POST请求的方法,对应HTTP的POST
提交
.put(url,data=None,**kwargs)
向HTML网页提交PUT请求的方法,对应HTTP的PUT
将提交的所有数据进行覆盖,没涉及到的原内容将被删除
.patch(url,data=None,**kwargs)
向HTML提交局部修改请求的方法,对应HTTP的PATCH
.delete(url,**kwargs)
向HTML网页提交删除的请求方法,对应HTTP的DELETE
Response对象的属性
.status_code
HTTP请求的int型返回状态,200成功
.text
HTTP响应的字符串格式,即url对应的页面内容
.encoding
从HTTP header中猜测的内容编码方式
.apparent_encoding
从内容分析出的编码方式
.contrnt
HTTP响应内容的二进制形式
Requests库异常
.ConnectionError
网络连接错误,如DNS查询失败,拒绝连接等
.HTTPError
HTTP错误异常
.URLRequired
URL缺失异常
.TooManyRedirects
超过最大定向次数,产生重定向错误
.ConnectTimeout
连接远程服务器超时异常
.Timeout
请求URL超时异常
.raise_for_statuw()
如果不是200,产生.HTTPError异常
爬取实例
京东商品界面爬取
亚马逊商品页面爬取
百度关键词提交
图片爬取
IP地址对属地查取
Robots协议
User-agent:* Disallow:/pop/*.html User-agent:EtaoSpider Disallow:*
所有网络爬虫不可访问/pop/*.html格式文件 EtaoSpider不可访问所有文件
类人行为可不参考Robots协议
标签Tag
标签 Tag :<p calss='title'等>....</p> 标签的名字<tag>.name=p 标签的属性<tag>.attrs={'calss'='title'} 标签内非属性字符串<tag>.string=.... comment标签内字符串的注释部分 备注格式<!--str-->
对应类型 tag为bs4.element.Tag类型 <tag>.name对应str类型 <tag>,.attrs对应dict类型 <tag>.string对应NavigableString类型 备注为mene类型
<tag>.string与<tag>.text区别 .string在tag包含多个节点的时候无法确定调用哪个子函数的内容,所以输出None .text可以将全部尖括号隐去,将剩余所有文本合并
Beautiful库
from bs4 import Beautifulsoup
soup=Beautifulsoup('html','html.parser')
将一段html文本转换为可操作的标签树,返回一个标签<soup>
'html.parser'为解析器
共有 'html.parser' 'lxml' 'xml' html5lib' 需要对应安装对应库
<tag>.<标签名>
访问该标签 存在多个同名标签时返回第一个
<tag>(str)
返回所有名字为str的标签组成的列表
<tag>.prettify()
在tag内自动增加'\n'与空格,返回修改后的文本 print(tag.prettify())输出按缩进分层的文本便于查看
isinstance(tag,类型)
如果字节符合该类型,函数返回True
注意:包括'\n'在内的字符串也视为一个节点
!
下行遍历
.contents
返回一个列表,存放其儿子节点
.children
子节点的迭代类型,与.contents类似,返回一个迭代器,用于循环遍历儿子节点
区别: contents与children类似 [0,1,2,3]与range(4)的区别
.descendants
子孙节点的迭代遍历,包括所有的子孙节点,返回一个迭代器,用于循环遍历
上行遍历
.parent
返回节点的父亲标签
soup.html.parent因为html为最高节点,没有父亲节点,系统返回html节点自己 soup.parent虽然soup也属于节点,但无相应属性,返回None
!
.parents
父亲节点的迭代遍历,返回一个迭代器,用于循环遍历先辈节点
平行遍历
平行遍历只作用于同一个父亲节点的范围内
!
.next_sibling
返回按照html文本顺序的下一个平行节点标签
.previous_sibling
返回按照html文本顺序的上一个平行节点标签
.next_siblings
迭代类型,返回按照html文本顺序的后续所有平行节点标签
.previous_siblings
迭代类型,返回按照html文本顺序的前续所有平行节点标签
信息的标记形式
XML
<p calss='title'等>....</p>
缩写形式 <img src='china.jpg' size='10'/>
实例: <person> <firstName>Tian</firstName> <lastName>song</lastName> <address><streetAddr>中关村南大街5号</streetAddr><city>北京市</city><zipcode>100081</zipcode> </address> <prof>Computer System</porf><porf>Security</prof> </person>
最早的通用信息标记语言,可扩展性号,繁琐 多用于网络上的信息交互于传递
注释形式 <!--str-->
JSON
有类型的键值对 key:valuw
'name' : '北京理工大学'
'name' : ['北京理工大学','延安自然科学院']
实例: { 'firstName' : 'Tian', 'lastName' : 'song, 'address' : {'streetAddr' : '中关村南大街5号’,'city' : '北京市''zipcode' : '100081' } 'prof' : ['computer','Security'] }
信息有类型,合适程序处理,较XML简洁 多用于移动运用云端和节点的信息通信 无注释
'name' : {'newName' : '北京理工大学''oldName' : '延安自然科学院' }
YAML
无类型键值对
name:北京理工大学
缩进表达所属关系 name: newName:北京理工大学 oldName:延安自然科学院
实例: firstName : Tian lastName : song address :streetAddr : 中关村南大街5号city : 北京市zipcode : 100081 prof : -Computer System -Security
信息无类型,文本信息比例最高,可读性好 多用于各类系统的配置文件,有注释易读
- 表达并列关系 name: -北京理工大学 -延安自然科学院
| 表达整块数据 #表示注释
信息的提取
<tag>.find_all(name,sttrs,recursive,string,**kwargs) 等价于<tag>(name,sttrs,recursive,string,**kwargs)
在tag标签内按格式查找所有节点组成的列表
name 对标签名称检索 .find_all(['a','b']多名称检索 .find_all(True)输出所有标签 .find_all(pile('b'))检索所有含名字b的标签
attrs 对标签的属性值内容检索 .find_all('p','course')输出所有属性值内容包含course字符串的标签p .find_all(id=pile('link'))输出所有属性值中id键对应的值的内容包含link字符串的标签
recursive=True/False 是否对子孙全部检索,默认True
string 对标签中字符串区域检索,用法上同
因为检索所有节点 字符串也属于节点 所以返回值为字符串的列表
其他拓展
<tag>.find()
只返回一个结果,参数上同
<tag>.find_parent()
在先辈节点中搜索,返回一个结果,参数上同
<tag>.find_parent()
在先辈节点中搜索,返回一个列表,参数上同
<tag>.find_next_sibling()
在后续平行节点中搜索,返回一个结果,参数上同
<tag>.find_next_siblings()
在后续平行节点中搜索,返回一个列表,参数上同
<tag>.find_previous_sibling()
在前续平行节点中搜索,返回一个结果,参数上同
<tag>.find_previous_siblings()
在前续平行节点中搜索,返回一个列表,参数上同
re库
r'正则' 与区别 '正则'
r'text'为原生字符串类型,text中的\仅与正则关系式有关,而非转义符 r'\b'=='\\b'表示单个数字
re库的主要功能函数
.search(pattern,string,flags=0)
在字符串中搜索匹配正则表达式的第一个位置 返回match对象 pattern:正则表达式 string:待匹配字符串 flags:正则表达式使用时的控制标记
glags: re.I re.IGNORECASE 忽略大小写 re.M re.MULTILINE 从每行开始分段匹配 re.S re.DOTALL .操作符能匹配所有字符,不开启时不能匹配回车
.match(pattern,sstring,flags=0)
从字符串的开始位置直接匹配正则表达式 返回match对象 pattern,string,flags上同
.findall(pattern,sstring,flags=0)
搜索字符串,匹配所有能匹配的子串 返回列表 pattern,string,flags上同
.split(pattern,sstring,maxsplit,flags=0)
将一个字符串按照正则表达式结果进行分隔 返回列表 pattern,string,flags上同 maxsplit表示最大分隔数 maxsplit为1表示分隔1次后字符串保持不变为一整体 分隔操作与字符串的相同 若以\w进行分隔'。。。。ab。。。' 分隔一次结果为[’。。。‘,'b。。。'] 分隔两次结果为['。。。','','。。。']
.finditer(pattern,sstring,flags=0)
搜索字符串,返回一个匹配结果的迭代类型 每个迭代元素为match对象 pattern,string,flags上同
.sub(pattern,repl,sstring,cout=0,flags=0)
在一个字符串中替换所有匹配的子串 返回替换后的字符串 pattern,string,flags上同 repl:替换匹配字符串的字符串 count:匹配的最大替换次数
match对象
属性
.string
待匹配的文本
.re
匹配时使用的patter(正则表达式)对象
.pos
正则表达式搜索文本的开始位置
.endpos
正则表达式搜索文本的结束位置
方法
.group(0)
获得匹配后的字符串
.start()
匹配字符串在原始字符串的开始位置
.end()
匹配字符串在原始字符串的结束位置
.span()
返回(.start(),.end())
pile(pattern,flags=0)
将正则表达式的字符串编译成正则表达式对象
pat=pile('正则表达式') rst=pat.search('text')
Scrapy库
scrapy爬虫框架
首先spider(爬虫)根据自身内容请求第一个要爬取的url,通过engine将url存入scheduler,由scheduler进行调控url的出列顺序,出列后经过engine向dowmloader请求下载,downloader从网络上下载内容经engine提交至spider,由spider(爬虫)进行数据处理,处理结束后提交至engine向piprline输出,这期间如果还需进行url爬取,再将url交至scheduler放入队列
scrapy的命令行格式 scrapy <command> [options] [args]
command: startproject创建一个新工程 genspider创建一个爬虫 settings获得爬虫配置信息 crawl运行一个爬虫 list 列出工程中所有爬虫 shell京东url调试命令行
scrapy startproject <name> [dir] scrapy genspider [options] <name> <domain> scrapy settings [options] scrapy crawl <spider> scrapy list scrapy shell [url]
domain为url为最高域,爬虫只能在这级以下爬取
具体文件介绍
projeck/ 外层目录 scrapy.cfg 部署scrapy爬虫的配置文件 project/ scrapy框架的用户自定义python代码 _init_.py 初始化脚本 items.py items代码模板 middlewares.py Middlewares代码模板 pipelines.pyPipelines代码模板 settings.pyScrapy爬虫的配置文件 spiders/ spaider代码模板目录(存放建立的爬虫)_init_.py初始文件_pycache_/ 缓存目录
爬虫的返回Response对象的属性
.url
HTTP相应的 URL地址,str类型的
.status
HTTP响应状态码,int类型的
.headers
Response对应的头部信息
.body
HTTP响应正文,bytes类型
.text
文本形式的HTTP响应正文,str类型,由response.body使用response.encoding解码得到
.flags
一组标记
.request
产生该HTTP响应的Requset对象
.encoding
HTTP响应正文的编码
.meta
response.request.meta 在构造request对象的时候,可以将要传递个响应处理函数的信息通过meta参数传入;响应处理函数处理响应时候,通过response.meta将信息取出
.selector
选择器对象用来提取response中的数据
.xpath
即xml路径语言,用来确定xml文档中某部分位置的语言
.css
一种选择器,用来提取页面内中的数据,但是不如xpath强大。
urljoin
用来构造绝对url,(爬取页面的时候跳转到第二页的时候需要重新构造request,这个时候用的到这个属性)
yield保留字的理解
def foo(): print("starting...") while True:res = yield 4print("res:",res) g = foo() print("*"*20) print(next(g)) print("*"*20) print(g.send(7)) print("*"*20) print(next(g))
首先yield类似return与print 在g=foo()行中遇到了yield 4,输出4后函数冻结 在print(next(g))中遇到next,函数被唤醒继续执行,上次于yield 4被冻结,这次继续yield 4后的给res的赋值操作,因为4被yield输出,等号右边无对象,将None赋予g,进行循环,遇到yield 4后再被冻结。 print('*'*20)输出 在print(g.send(7))行中遇到send,函数被唤醒,同理继续赋值操作,但send函数把7作为等号右边内容赋予g,继续循环,遇到yield 4后再被冻结 print('*'*20)输出 在print(next(g))行中遇到send,函数被唤醒,同理将None赋予g,继续循环,遇到yield 4后被冻结
输出: starting... 4 ******************** res: None 4 ******************** res:7 4 ******************** res:None 4
生成器
def gen(n): for i in range(n):yield i**2 for i in gen(5): print(i,' ',end='')
输出: 0 1 4 9 16
CSS Selector
<HTML>.css('a::attr(href)').extract()