Python网络爬虫【2】--正则表达式、Scrapy库的使用

单元四、信息组织与提取方法

1)信息标记的三种方式

XML, JSON, YAML

2)信息提取的一般方法

  • 方法一:完整解析信息的标记形式,再提取关键信息

    XML JSON YAML

    需要标记解析器 例如:bs4库的标记树遍历

    优先:信息解析准确

    缺点:提取过程繁琐,速度慢

  • 方法二:无标记形式,直接搜索关键信息

    搜索

    对信息的文本查找函数即可。

    优点:提取过程简单,速度较快

    缺点:提取结果准确性与信息内容有关

  • 方法三:融合方法:结合形式解析与搜索方法,提取关键信息

    XML JSON YAML 搜索

    需要标记解析器及文本查找函数

实例:提取HTML中所有的URL链接

思路;1)搜索到所有的标签

​ 2)解析标签格式,提取href后的链接内容

3)基于bs4的HTML内容查找方法

<tag>.fint_all(name, attrs, recursive, string, **kwargs)
其等价于<tag>(..)


返回:
一个列表类型,存储查找的结果

选项:
name: 对标签名称的检索字符串
attrs: 对标签属性值的检索字符串,可标注属性索引
recursive: 是否对子孙全部索引,默认True
string: <>...</>中字符串区域的检索字符串
**kwargs: 

参数name:

>>> soup.find_all('a') ## 查找所有a标签
>>> soup.find_all(['a', 'b']) ## 查找所有a, b标签

参数attrs:

>>> soup.find_all('p', 'course')
>>> soup.find(id = 'link1')

参数recursive:

>>> soup.find_all('a', recursive = True)
>>> soup.find_all('a', recursive = False)

参数string:

>>> soup.find_all(string = 'Basic Python')

简写:

<tag>(…) 等价于 <tag>.find_all(…)

soup(…) 等价于 soup.find_all(…)

拓展方法:

方法说明
<>.find()搜索且只返回一个结果,字符串类型,同.find_all()参数
<>.find_parents()在先辈节点中搜索,返回列表类型,同.find_all()参数
<>.find_parent()在先辈节点中返回一个结果,字符串类型, 同.find_all()参数
<>.find_next_siblings()在后续平行节点中搜索,返回列表类型, 同.find_all()参数
<>.find_next_sibling()在后续平行节点中返回一个结果,字符串类型, 同.find_all()参数
<>.find_previous_siblings()在前续平行节点中搜索,返回列表类型, , 同.find_all()参数
<>.find_previous_sibling()在前续平行节点中返回一个结果,字符串类型, 同.find_all()参数

案例:爬取最好中国大学网

import requests
import bs4
from bs4 import BeautifulSoup


def getHTMLText(url):
    try:
        r = requests.get(url)
        r.raise_for_status()
        r.encoding = r.apparent_encoding
        return r.text
    except:
        return ""


def fillUnivList(ulist, html):
    soup = BeautifulSoup(html, 'html.parser')
    for tr in soup.find('tbody').children:
        if isinstance(tr, bs4.element.Tag):
            tds = tr('td')
            ulist.append([tds[0].string, tds[1].string, tds[4].string])


def printUnivList(ulist, num):
    tplt = "{0:^10}\t{1:{3}^10}\t{2:^10}"
    print(tplt.format("排名", "学校", "总分", chr(12288)))
    for i in range(num):
        u = ulist[i]
        print(tplt.format(u[0], u[1], u[2], chr(12288)))


def main():
    uinfo = []
    url = 'http://www.zuihaodaxue.com/zuihaodaxuepaiming2020.html'
    html = getHTMLText(url)
    fillUnivList(uinfo, html)
    printUnivList(uinfo, 20)

main()

单元五、正则表达式

1)正则表达式的概念

正则表达式的常用操作符

操作符说明实例
.表示任何单个字符串
[ ]字符集,对单个字符给出取值范围[abc]表示a、b、c,[a-z]表示a到z单个字符
[^ ]非字符集,对单个字符给出排除范围[^abc]表示非a或b或c的单个字符
*前一个字符出现0次或无限次拓展abc*表示ab、abc、abcc、abccc等
+前一个字符出现1次或无限次拓展abc+表示abc、abcc、abccc等
前一个字符出现0次或1次拓展abc?表示ab、abc
|左右表达式任意一个abc|def表示abc、def
{m}拓展前一个字符m次ab{2}c表示abbc
{m, n}拓展前一个字符m至n次(含n)ab{1, 2}c表示abc、abbc
^匹配字符串开头^abc表示abc且在一个字符串的开头
$匹配字符串结尾abc$表示abc且在一个字符串的结尾
()分组标记,内部只能使用|操作符(abc)表示abc,(abc|def)表示abc、def
\d数字,等价于[0-9]
\w单词字符,等价于[A-Za-z0-9_]

2)Re库的使用

Re库主要功能函数

函数说明
re.search()在一个字符串中搜索匹配正则表达式的第一个位置,返回一个match对象
re.match()从一个字符串的开始位置起匹配正则表达式,返回match对象
re.findall()搜索字符串,以列表类型返回全部能匹配的子串
re.split()将一个字符串按照正则表达式匹配结果进行分割,返回列表类型
re.finditer()搜索字符串,返回一个匹配结果的迭代对象,每个迭代对象都是match对象
re.sub()在一个字符串中替换所有匹配正则表达式的子串,返回替换后的字符串

1 re.search()

re.search(pattern, string, flags=0)

选项:
patten: 正则表达式的字符串或原生子串表达式
string: 待匹配字符串
flags: 正则表达式使用时的控制标记

flags的常用标记:

常用标记说明
re.I re.IGNORECASE忽略正则表达式的大小写,|A-Z|能够匹配小写字符
re.M re.MULTILINE正则表达式中的^操作符能够将给定字符串的每行当作匹配开始
re.S re.DOTALL正则表达式中的.操作符能够匹配所有字符,默认匹配除换行外的所有字符

2 re.match

re.match(pattern, string, flags=0)

选项:
patten: 正则表达式的字符串或原生子串表达式
string: 待匹配字符串
flags: 正则表达式使用时的控制标记

3 re.findall

re.findall(pattern, string, flags=0)

选项:
patten: 正则表达式的字符串或原生子串表达式
string: 待匹配字符串
flags: 正则表达式使用时的控制标记

4 re.split

re.split(pattern, string, maxsplit=0, flags=0)

选项:
patten: 正则表达式的字符串或原生子串表达式
string: 待匹配字符串
maxsplits: 最大分割数,剩余部分作为最后一个元素输出
flags: 正则表达式使用时的控制标记

5 re.finditer

re.finditer(pattern, string, flags=0)

选项:
patten: 正则表达式的字符串或原生子串表达式
string: 待匹配字符串
flags: 正则表达式使用时的控制标记

6、re.sub

re.sub(pattern, repl, string, count = 0, flags=0)

选项:
patten: 正则表达式的字符串或原生子串表达式
repl: 	替换匹配字符串的字符串
string: 待匹配字符串
count: 匹配的最大替换次数
flags: 正则表达式使用时的控制标记

3)Re库的另一种等价用法

在这里插入图片描述

regex = re.compile(pattern, flags = 0)

选项:
patten: 正则表达式的字符串或原生子串表达式
flags: 正则表达式使用时的控制标记
函数说明
regex.search()在一个字符串中搜索匹配正则表达式的第一个位置,返回一个match对象
regex.match()从一个字符串的开始位置起匹配正则表达式,返回match对象
regex.findall()搜索字符串,以列表类型返回全部能匹配的子串
regex.split()将一个字符串按照正则表达式匹配结果进行分割,返回列表类型
regex.finditer()搜索字符串,返回一个匹配结果的迭代对象,每个迭代对象都是match对象
regex.sub()在一个字符串中替换所有匹配正则表达式的子串,返回替换后的字符串

4)Re库的match对象

Match对象的属性

属性说明
.string待匹配的文本
.re匹配时使用的pattern对象(正则表达式)
.pos正则表达式搜索文本的开始位置
.endpos正则表达式搜索文本的结束位置

Match对象的方法

方法说明
.group(0)获得匹配后的字符串
.start()匹配字符串在原始字符串的开始位置
.end()匹配字符串在原始字符串的结束位置
.span()返回(.start(), .end())

5)Re库的贪婪匹配和最小匹配

Re库默认使用贪婪匹配,即输出匹配最长的子串。

最小匹配操作符

操作符说明
*?前一个字符0次,或无限次扩展,最小匹配
+?前一个字符1次,或无限次扩展,最小匹配
??前一个字符0次,或1次扩展,最小匹配
{m, n}?拓展前一个字符m至n次(含n),最小匹配

单元六、Scrapy爬虫框架

1)Scrapy爬虫框架解析

在这里插入图片描述

各个模块说明:

  • Engine——控制所有模块的数据流/根据条件触发事件【不需要用户修改】
  • Downloader——根据请求下载网页【不需要用户修改】
  • Scheduler——对所有爬取请求进行调度管理【不需要用户修改】
  • Spiders——解析Downloader返回的响应(Response);产生爬取项(scraped item),产生额外的爬取请求(Request)【需要用户编写配置代码】
  • Item Pipelines——以流水线方式处理Spider产生的爬取项;由一组操作顺序组成,类似流水线,每个操作是一个Item Pipeline类型;可能操作包括:清理、检验和查重爬取项中的HTML数据、将数据存储到数据库中。【需要用户编写配置代码】
  • ————————————————————————————————————
  • Downloader Midderware——实施Engine、Scheduler和Downloader之间进行用户可配置的控制,可实现修改、丢弃、新增请求或响应【用户可编写配置代码】
  • Spider Middleware——对请求和爬取项的再处理,可实现修改、丢弃、新增请求或爬取项【用户可编写配置代码】

2)Scrapy爬虫的常用命令

Scrapy是为持续运行设计的专业爬虫框架,提供操作的Scarpy命令行。

命令说明格式
startproject创建一个新工程scrapy startproject [dir]
genspider创建一个爬虫scrapy genspider [options]
settings获得爬虫配置信息scrapy settings [options]
crawl运行一个爬虫scrapy crawl
list列出工程中所有爬虫scrapy list
shell启动URL调试命令行scrapy shell [url]

3)scrapy 爬虫实例

使用scrapy爬取页面:http://www.python123.io/ws/demo.html

步骤:

1 建立一个Scrapy爬虫工程
在这里插入图片描述

生成的工程文件

python123demo——》外层目录

​ scrapy.cfg——》部署Scrapy爬虫的配置文件

​ python123demo——》Scrapy框架的用户自定义Python代码

​ __ init __.py——》初始化脚本

​ items.py——》Items代码模块(继承类)

​ middlewares.py——》Middlewares代码模板(继承类)

​ pipelines.py——》Pipelines代码模板(继承类)

​ settings.py——》Scrapy爬虫的配置文件

​ spiders/——》Spriders代码模板目录(继承类)

​ __ init __.py——》初始文件,无需修改

​ __ pycache __/——》缓存目录,无需修改

2 在工程中产生一个Scrapy爬虫(创建了一个py脚本存放在spiders目录下)
在这里插入图片描述

在spiders目录下产生一个demo.py文件,查看文件:

在这里插入图片描述
​ 这里的parse()用于处理响应,解析内容形成字典,发现新的URL爬取请求。

3 配置产生的spider爬虫

在这里插入图片描述

4 运行爬虫,获取网页

在这里插入图片描述

demo.py两个等价版本的区别

在这里插入图片描述
yield关键字:

yield 《——》生成器:不断产生值的函数

生成器每次产生一个值(yield语句),就会被冻结,被唤醒后再从上次的位置继续再产生一个值。

4)Scrapy爬虫的基本使用

Scrapy爬虫的使用步骤:

步骤一:创建一个工程和Spider模板
步骤二:编写Spider
步骤三:编写Item Pipeline
步骤四:优化配置策略

Scrapy爬虫的数据类型:

Request类
Response类
Item类

Request类
class.Scrapy.http.Request()

  • Request对象表示一个HTTP请求。
  • 由Spider生成,由Downloader执行
属性说明
.urlRequest对应的请求URL地址
.method对应的请求方法,‘GET’‘POST’等
.headers字典类型风格的请求头
.body请求内容主体,字符串类型
.meta用户添加的拓展信息,在Scrapy内部模块间传递信息使用
.copy()复制该请求

Response类
class.Scrapy.http.Response()

  • Response对象表示一个HTTP响应。
  • 由Downloader成,由Spider处理
属性或方法说明
.urlResponse对应的URL地址
.statusHTTP状态码,默认200
.headersResponse对应的头部信息
.bodyResponse对应的内容信息,字符串类型
.flags一组标记
.request产生Response类型的Request对象
.copy复制该响应

Item类
class.scrapy.item.item()

  • Item对象表示一个从HTML页面中提取的信息内容
  • 由Spider生成,由Item Pipeline处理
  • Item类似字典类型,可以按照字典类型操作

5)Scrapy爬虫提取信息的方法

Scrapy爬虫支持多种HTML信息提取方法:

  • Beautiful Soup
  • lxml
  • re
  • XPath Selector
  • CSS Selector

CSS Selector的基本使用

<html>.css('a::attr=(href)').extract()
获得对应的标签信息

注:
a:标签名称
href:标签属性

6)配置并发连接选项—settting.py文件

选项说明
CONCURRENT_REQUESTSDownloader最大并发下载数量,默认32
CONCURRENT_ITEMSItem Pipeline最大并发ITEM处理数量,默认100
CONCURRENT_REQUESTS_PRE_DOMAIN每个目标域名最大的并发请求数,默认8
CONCURRENT_REQUESTS_PER_IO每个目标IP最大的并发请求数,默认为0,非0有效

参考资料:
【1】Mooc - Python爬虫与信息提取

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值