XML, JSON, YAML
方法一:完整解析信息的标记形式,再提取关键信息
XML JSON YAML
需要标记解析器 例如:bs4库的标记树遍历
优先:信息解析准确
缺点:提取过程繁琐,速度慢
方法二:无标记形式,直接搜索关键信息
搜索
对信息的文本查找函数即可。
优点:提取过程简单,速度较快
缺点:提取结果准确性与信息内容有关
方法三:融合方法:结合形式解析与搜索方法,提取关键信息
XML JSON YAML 搜索
需要标记解析器及文本查找函数
实例:提取HTML中所有的URL链接
思路;1)搜索到所有的标签
2)解析标签格式,提取href后的链接内容
参数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()正则表达式的常用操作符
操作符说明实例.表示任何单个字符串[ ]字符集,对单个字符给出取值范围[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_]Re库主要功能函数
函数说明re.search()在一个字符串中搜索匹配正则表达式的第一个位置,返回一个match对象re.match()从一个字符串的开始位置起匹配正则表达式,返回match对象re.findall()搜索字符串,以列表类型返回全部能匹配的子串re.split()将一个字符串按照正则表达式匹配结果进行分割,返回列表类型re.finditer()搜索字符串,返回一个匹配结果的迭代对象,每个迭代对象都是match对象re.sub()在一个字符串中替换所有匹配正则表达式的子串,返回替换后的字符串flags的常用标记:
常用标记说明re.I re.IGNORECASE忽略正则表达式的大小写,|A-Z|能够匹配小写字符re.M re.MULTILINE正则表达式中的^操作符能够将给定字符串的每行当作匹配开始re.S re.DOTALL正则表达式中的.操作符能够匹配所有字符,默认匹配除换行外的所有字符Match对象的属性
属性说明.string待匹配的文本.re匹配时使用的pattern对象(正则表达式).pos正则表达式搜索文本的开始位置.endpos正则表达式搜索文本的结束位置Match对象的方法
方法说明.group(0)获得匹配后的字符串.start()匹配字符串在原始字符串的开始位置.end()匹配字符串在原始字符串的结束位置.span()返回(.start(), .end())Re库默认使用贪婪匹配,即输出匹配最长的子串。
最小匹配操作符
操作符说明*?前一个字符0次,或无限次扩展,最小匹配+?前一个字符1次,或无限次扩展,最小匹配??前一个字符0次,或1次扩展,最小匹配{m, n}?拓展前一个字符m至n次(含n),最小匹配各个模块说明:
Engine——控制所有模块的数据流/根据条件触发事件【不需要用户修改】Downloader——根据请求下载网页【不需要用户修改】Scheduler——对所有爬取请求进行调度管理【不需要用户修改】Spiders——解析Downloader返回的响应(Response);产生爬取项(scraped item),产生额外的爬取请求(Request)【需要用户编写配置代码】Item Pipelines——以流水线方式处理Spider产生的爬取项;由一组操作顺序组成,类似流水线,每个操作是一个Item Pipeline类型;可能操作包括:清理、检验和查重爬取项中的HTML数据、将数据存储到数据库中。【需要用户编写配置代码】————————————————————————————————————Downloader Midderware——实施Engine、Scheduler和Downloader之间进行用户可配置的控制,可实现修改、丢弃、新增请求或响应【用户可编写配置代码】Spider Middleware——对请求和爬取项的再处理,可实现修改、丢弃、新增请求或爬取项【用户可编写配置代码】Scrapy是为持续运行设计的专业爬虫框架,提供操作的Scarpy命令行。
命令说明格式startproject创建一个新工程scrapy startproject [dir]genspider创建一个爬虫scrapy genspider [options] settings获得爬虫配置信息scrapy settings [options]crawl运行一个爬虫scrapy crawl list列出工程中所有爬虫scrapy listshell启动URL调试命令行scrapy shell [url]使用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语句),就会被冻结,被唤醒后再从上次的位置继续再产生一个值。
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类似字典类型,可以按照字典类型操作Scrapy爬虫支持多种HTML信息提取方法:
Beautiful SouplxmlreXPath SelectorCSS SelectorCSS Selector的基本使用
<html>.css('a::attr=(href)').extract() 获得对应的标签信息 注: a:标签名称 href:标签属性参考资料: 【1】Mooc - Python爬虫与信息提取