python数据分析复盘——爬虫相关库

Requests、BeautifulSoup、re、lxml、css selector 、scrapy


1.Requests

1.1 Requests的7个主要方法

其中,request()方法是其它方法的基础方法,get()方法用的多一些,本人没在实际爬取中用过其它方法。

requests.request() 构造一个请求,支撑以下各方法的基础方法
requests.get() 获取HTML网页的主要方法,对应于HTTP的GET
requests.head() 获取HTML网页头信息的方法,对应于HTTP的HEAD
requests.post() 向HTML网页提交POST请求的方法,对应于HTTP的POST
requests.put() 向HTML网页提交PUT请求的方法,对应于HTTP的PUT
requests.patch() 向HTML网页提交局部修改请求,对应于HTTP的PATCH

1.2 get()方法

r= requests.get(url)
r:返回一个包含服务器资源的Response对象
 requests.get(url):构造一个向服务器请求资源的Request对象

requests.get(url, params=None, **kwargs)

1.3 Requests库的2个重要对象(Request、Response)

 ![这里写图片描述](https://img-blog.csdn.net/20170911155328722?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvbWxfMTAxOQ==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
 由上图所示,request请求返回的是Response对象,可以提取对应的头部等信息。一般而言,除非是需要登录验证的post请求中,需要通过get请求拿到请求的头部信息,然后加到post请求头部信息里,用来登陆验证。

这里写图片描述

返回的Response对象有以上的属性,其中r.status_code状态码可以进行请求控制。

这里写图片描述

可以通过检测的编码替换现有的编码,以正常解码。需要注意的是,r.encoding()的执行,耗费的时间相对较多,如果注重效率,编码又比较固定,就考虑用固定编码给r.apparent_encoding赋值,以减少运行时间。

1.4 Response异常

r.raise_for_status() 如果不是200,产生异常 requests.HTTPError

该方法可以用来作请求异常控制的中检测。


1.5 通用框架

def getHTMLText(url):
    try:
        r = requests.get(url, timeout=30)
        r.raise_for_status()#检测异常
        r.encoding = r.apparent_encoding#改http中给定编码方式为根据文本(r.text)猜测的编码方式。
        return r.text
    except:
        print("请求出错")
        return ""

1.6 Requests方法解析(requests.get())

requests.get(url, params=None, **kwargs)

**kwargs

data                json
headers             cookies
auth                files
timeout             proxies
allow_redirects     stream
verify              cert

2.BeautifulSoup

2.1 什么是BeautifulSoup

 BeautifulSoup是解析、遍历、维护标签树(html)的库。
 **解析html**:解析方式可以有4种,包括lxml。
 **遍历标签树**:通过上行下行和平行遍历迭代器遍历,结合基本元素(tag、name、tag.string等等)提取内容。
 **维护标签树**:以美观的形式输出html(prettify())
**编码**:bs4库将任何HTML输入都变成utf‐8编码,python3默认支持utf-8

2.2 Beautiful Soup库解析器

如下图所示,一共可以有4中方式,其中解析速度:lxml > html.parser
测试了下,lxml和 html.parser都会缺失的标签补上。因为lxm是用c写的,所以理论上lxml速度会快些。另外的解析方式不太了解,也没用过,暂不理b( ̄▽ ̄)d
这里写图片描述


2.3 BeautifulSoup类的基本元素

可以通过基本元素定位和提取标签的内容。如通过[tag].attrs可以以字典的形式提取出标签内属性名字和值。通过[tag].string的方式提取非属性字符串。区别注释的方法是,通过type判断类型。

 <p class=“title”></p>

基本元素            说明
Tag             标签,最基本的信息组织单元,分别用<></>标明开头和结尾
Name            标签的名字,<p></p>的名字是'p',格式:<tag>.name
Attributes      标签的属性,字典形式组织,格式:<tag>.attrs
NavigableString 标签内非属性字符串,<></>中字符串,格式:<tag>.string
Comment         标签内字符串的注释部分,一种特殊的Comment类型

2.4 基于bs4库的HTML内容遍历方法

BeautifulSoup提供了三种遍历方式,上行、下行和平行 遍历,如下图所示:
这里写图片描述

(1)下行遍历:

   属性       说明
.contents     子节点的列表,将<tag>所有儿子节点存入列表
.children     子节点的迭代类型,与.contents类似,用于循环遍历儿子节点
.descendants  子孙节点的迭代类型,包含所有子孙节点,用于循环遍历
for child in soup.body.children:
    print(child)  #遍历儿子节点
for child in soup.body.descendants:
    print(child)  #遍历子孙节点

(2)上行遍历:
这里写图片描述
尤其注意画红线部分,所有的先辈节点中包含soup本身。即整个html文档。

(3)平行遍历:

属性              说明
.next_sibling       #返回按照HTML文本顺序的下一个平行节点标签
.previous_sibling   #返回按照HTML文本顺序的上一个平行节点标签
.next_siblings      #迭代类型,返回按照HTML文本顺序的后续所有平行节点标签
.previous_siblings  #迭代类型,返回按照HTML文本顺序的前续所有平行节点标签

这里写图片描述

这里写图片描述


2. 5基于bs4库的HTML格式输出

这里写图片描述


2.6 BeautifulSoup和lxml的异同

异                               同   
BS有4种解析方法                   都可以用来解析html和xml         
BS的接口比较简洁                   都支持cssselector和xpath
BS的遍历方式比较多(上 下 平行遍历) 
BS容易上手
lxml是用c写的,速度相对较快

3.Re、Xpath、cssSelecor

3.1正则表达式:

正则表达式:用来简洁表达一组字符串的表达式(包括字符和操作符)。
操作符:
这里写图片描述
这里写图片描述
表达式实例:
这里写图片描述

这里写图片描述


3.2 re模块

import re
string222='1995我 的天哦,我的妈呀 公元1996 1231年'

# 1.—————————————第1种方式(函数式用法)————————————

#findall
ls=re.findall(r'[1-9]\d{3}','1995 公元1996 1231年')
if ls:
    print(ls)

#match 匹配到的第一个
match2=re.match(r'[1-9]\d{3}','1995 公元1996 1231年')
if match2:
    print(match2.group(0))

#split 以匹配到的字符串分割
ls2=re.split(r'[1-9]\d{3}',string222,maxsplit=1)
if ls2:
    print(ls2)
#sub 替换匹配到的字符串
ls3=re.sub(r'[1-9]\d{3}',repl='  替换了这里  ',string=string222)
print(ls3)



>>>
['1995', '1996', '1231']
1995
['', '我 的天哦,我的妈呀 公元1996 1231年']
  替换了这里  我 的天哦,我的妈呀 公元  替换了这里     替换了这里  年
# 2.—————————————法2(函数式用法)————————————
# 一次编译,多次使用
pat=re.compile(r'[1-9]\d{3}')#编译
rst=pat.search(string222)   #搜索
print(rst.group(0))         #结果
print(rst.string)           #待匹配的文本
print(rst.re)               #使用的正则表达式
print(rst.span())           #返回(起始位置,结束位置)

>>>
1995
1995我 的天哦,我的妈呀 公元1996 1231年
re.compile('[1-9]\\d{3}')
(0, 4)
# 3.—————————————match对象————————————
# search和match方法返回的都是match对象
# ##属性
# .string:待匹配的文本
# .re:匹配时使用的pattern对象(正则表达式)
# .pos(正则表达式搜索文本的开始位置)
# .enpos:正则表达式搜索文本的结束位置
# ##方法:
# group(0)
# .start()
# .end()
# .span() 开始合结束位置
# 4.—————————————贪婪匹配(默认)————————————
match3=re.search(r'PY.*N','PYNABNCNDNFFFFF')
print(match3.group(0))
match4=re.search(r'PY.*?N','PYNABNCNDNFFFFF')
print(match4.group(0))
match5=re.search(r'PY.+?N','PYNABNCNDNFFFFF')
print(match5.group(0))
# 有长度的地方就有懒惰
# * → *?            任意次   →  0次
# + → +?            一次以上 →  1次
# ? → ??            0/1次   →  0次
# {m,n} → {m,n}?    m到n次  →  m次

>>>
PYNABNCNDN
PYN
PYNABN

3.3 Xpath

# coding=utf-8

el = tree.xpath('//input[@name="authenticity_token"]')[0] #//表示从匹配选择的当前节点选择文档中的节点,而不考虑它们的位置。根节点为/
authenticity_token = el.attrib['value']

r = s.post(SESSION_URL, data=data)
el = tree.xpath('//ul[@id="repo_listing"]')[0] #模式为节点[@+属性='值'] 返回列表
el.xpath('//li[contains(@class, "public")]')
#多次截取
print (el.xpath('//span[@class="repo"]')[0].text)
print (tree.xpath('//ul[@id="repo_listing"]//li[contains(@class, "public")]//\span[@class="repo"]')[0].text)

3.4 css selecors:

可转换为xpath执行

from cssselect import GenericTranslator, SelectorError
try:
    expression = GenericTranslator().css_to_xpath('div.content')
except SelectorError:
    print('Invalid selector.')

print(expression)
输出:descendant-or-self::div[@class and contains(concat(' ', normalize-space(@class), ' '), ' content ')]

from lxml.etree import fromstring
document = fromstring('.....')

document.xpath(expression)#执行转换后的cssselector

html解析和提取参考:

1.Python正则表达式
2.CSS 选择器参考手册
3.XPath 语法
4.BeautifulSoup :一些常用功能的使用和测试
5.BeautifulSoup的使用,代码比较乱


4.Scrapy

4.1 Scrapy简介

Scrapy是一个快速功能强大的网络爬虫框架,框架的意思就是不止一个库,是很多模块的集合,只需要进行一些配置就可以实现很powerf的功能。
Scrapy是一个开源、协作的框架。


4.2 Scrapy VS Requests

相同点:
两者都可以进行页面请求和爬取,Python爬虫的两个重要技术路线
两者可用性都好,文档丰富,入门简单
两者都没有处理js、提交表单、应对验证码等功能(可扩展)

不同点:

这里写图片描述


4.3 Scrapy框架结构

”5+2结构“:5个模块,2个中间件
这里写图片描述

这里写图片描述
如下图所示:需要编写和配置的只有spider、 item、pipelines
这里写图片描述


4.4 Scrapy常用命令

这里写图片描述


5.Scrapy实例

参见:南方都市报scrapy爬虫


6.爬虫待发掘

6.1 非框架并行爬虫

多线程(效果不太理想,慢、漏)

6.2 会话管理

session 共享等

6.3 ip池、http请求头部池

6.4 分布式爬虫(上云)


以上内容部分整理自:Python网络爬虫与信息提取

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值