Datawhale Task2 xpath,bs4,re,爬取丁香园留言板

@xpath

xpath简介

  1. XML 文档中查找信息的语言
  2. XML 文档中对元素和属性进行遍历
  3. 与XPath相似的便是CSS的选择器,但XPath有更强大的地方,比如它可以定位到body元素下具体位置上的p或可以选择前N个p:

xpath书写

nodeName选取名称为nodeName的节点
/从根节点选取
//选择元素后代元素,必须在后面跟上nodeName
.选取当前节点
选取当前节点的父节点
@选取属性节点(@是attribute的缩写)

谓语

谓语用于在查找节点时提供更详尽的信息,谓语被嵌在方括号中

/root/child[3] {选取root元素的第三个child子元素,注意,这和数组下标不一样,从1开始计数
//child[@attr] {选取所有具有属性attr的child元素
//child[@attr=“val”]/desc {选取所有属性attr的值为val的child元素的子元素desc
//child[desc] {选取所有的有desc子元素的child
//child[position()>3] {position()是XPath中的一个函数,表示节点的位置
//child[@attr>12] {XPath表达式还可以进行数值比较,该表达式将选取attr属性值大于12的child元素
//child[last()] {last()函数返回节点列表最后的位置,该表达式将选取最后一个child元素

通配符

*和CSS中的选择符一样,这将匹配任何元素节点
@*匹配任何属性节点
node()匹配任何类型的节点

/root/* {选取根元素下面的所有子元素
/root/node() {选取根元素下面的所有节点,包括文本节点
//* {选取文档中所有元素
//child[@] {选取所有具有属性的child元素
//@
{选取所有的属性节点

组合路径

xpath用"|"来组合多个路径的语法

/root | /root/child {选取根元素root与它下面的子元素child
//child | //desc {选取所有的child元素与desc元素

|

计算两个节点集
div除法,因为/已经被作为路径符了,所以不能用来作为除法标识
mod取余

xpath轴

轴可定义某个相对于当前节点的节点集。

ancestor选取当前节点的所有先辈(父、祖父等)
ancestor-or-self选取当前节点的所有先辈(父、祖父等)以及当前节点本身
attribute选取当前节点的所有属性
child选取当前节点的所有子元素。
descendant选取当前节点的所有后代元素(子、孙等)
descendant-or-self选取当前节点的所有后代元素(子、孙等)以及当前节点本身。
following选取文档中当前节点的结束标签之后的所有节点。
namespace选取当前节点的所有命名空间节点
parent选取当前节点的父节点。
preceding选取文档中当前节点的开始标签之前的所有节点。
preceding-sibling选取当前节点之前的所有同级节点。
self选取当前节点。

xpath表达式 = “/”+“步”
“步” = 轴+节点测试+谓语

XPathResult.ANY_UNORDERED_NODE_TYPE返回匹配节点的节点集合,但顺序可能与文档中的节点的顺序不匹配
XPathResult.ANY_TYPE返回符合XPath表达式类型的数据
XPathResult.ORDERED_NODE_SNAPSHOT_TYPE返回节点集合快照,在文档外捕获节点,这样将来对文档的任何修改都不会影响这个节点列表。节点集合中的节点与它们出现在文档中的顺序一样
XPathResult.STRING_TYPE返回字符串值
XPathResult.UNORDERED_NODE_ITERATOR_TYPE返回匹配节点的节点集合,不过顺序可能不会按照节点在文档中出现的顺序排列
XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE返回节点集合快照,在文档外捕获节点,这样将来对文档的任何修改都不会影响这个节点列表。节点集合中的节点和文档中原来的顺序不一定一样。

下面是使用ORDERED_NODE_ITERATOR_TYPE的例子:

var xmlDom = getXMLDOM();//我们之前写的跨浏览器的XML DOM加载函数
loadXMLFile(xmlDom,"text.xml");
var evaluator = new XPathEvaluator();
var result =evaluator.evaluate("/root",xmlDom,null,XPathResult.ORDERED_NODE_ITERATOR_TYPE,null);
var node;
if (result) {//执行失败会返回null
	while(node=result.iterateNext()) {//这个列表必须使用iterateNext方法遍历
		alert(node.tagName);
	}
}

爬取丁香园-用户名和回复内容

爬取思路:

  1. 获取url的html
# 导入库
from lxml import etree
import requests

url = "http://www.dxy.cn/bbs/thread/626626#626626"

# 获取url的html
req = requests.get(url)
html = req.tex

2.lxml解析html

# lxml解析html
tree = etree.HTML(html) 
tree

3.利用Xpath表达式获取user和content

# 利用Xpath表达式获取user和content
user = tree.xpath('//div[@class="auth"]/a/text()')
print(user)
content = tree.xpath('//td[@class="postbody"]')

4.保存爬取的内容并打印

results = []
for i in range(0, len(user)):
    print(user[i].strip()+":"+content[i].xpath('string(.)').strip())
    print("*"*80)
    # 因回复内容中有换行等标签,需要用string()来获取数据
    results.append(user[i].strip() + ":  " + content[i].xpath('string(.)').strip())
    # 打印爬取的结果
for i,result in zip(range(0, len(user)),results):
    print("user"+ str(i+1) + "-" + result)
    print("*"*100)

打印结果

Beautiful Soup(bs4)

1.Beautiful Soup库是解析、遍历、维护“标签树”的功能库,对应一个HTML/XML文档的全部内容
2.BeautifulSoup类的基本元素:
在这里插入图片描述
图片来源:https://www.icourse163.org/learn/BIT-1001870001#/learn/content?type=detail&id=1214620498&cid=1218397659
3.基于bs4库的HTML遍历方法
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

4.bs4的引用

from bs4 import BeautifulSoup

!严格区分大小写

未完待更……

实战:中国大学排名定向爬取

# 导入库
import requests
from bs4 import BeautifulSoup
import bs4

1.从网络上获取大学排名网页内容

# 从网络上获取大学排名网页内容
def getHTMLText(url):
    try:
        r = requests.get(url, timeout=30) 
        r.raise_for_status()
        r.encoding = r.apparent_encoding
        return r.text
    except:
        return ""

2.提取网页内容中信息到合适的数据结构(二维数组)
(1)查看网页源代码,观察并定位到需要爬取内容的标签;
(2)使用bs4的查找方法提取所需信息-'排名,学校名称,总分

# 提取网页内容中信息到合适的数据结构(二维数组)
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[3].string])  

3.利用数据结构展示

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

4.输出

def main():
    uinfo = []
    url = 'https://www.zuihaodaxue.cn/zuihaodaxuepaiming2019.html'
    html = getHTMLText(url)
    fillUnivList(uinfo, html)
    printUnivList(uinfo, 20) # 20 univs
main()

正则表达式(re)

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
未完待续……

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值