Task 2 Xpath,bs4&正则表达式

Xpath,bs4&正则表达式

采用lxml+xpath提取内容

啥是XML?
可扩展标记语言。标记电子文件,使其具有结构性的标记语言。

啥是Xpath?

是XML路径语言,用来确定XML文档中某部分位置;包括七种类型的节点:元素、属性、文本、命名空间、处理指令、注释及文档。可用来在XML文档中对元素和属性进行遍历。

一些Xpath的路径表达式:
Body/p[position()=4] //选择body子元素中的第4个P元素;
Body/p[position()< 3]//选择body子元素中的前2个P元素。

Xpath的书写:
/选取文档节点;
.是当前节点;
…是当前节点的父节点;
@ 选取属性节点。

谓语书写:
/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元素

bs4

Beautiful Soup库
是解析、遍历、维护“标签树”的功能库
安装、导入与基础:

pip install beautifulsoup4#安装库功能
from bs4 import BeautifulSoup#调用bs4
import requests
res=request.get(‘待爬取网址’)
demo=r.text #则type(demo)为str
soup=BeautifulSoup(<a>html</a>’,’html.parser')#创建Beautiful Soup对象
print(soup.prettify())#美化输出内容,为 HTML文本增加换行,输出更有层次感,标签名会自动分段,看起来很清晰,方便查找并提取需要的信息

列举soup对象的常用功能&上下和同级遍历&查找

soup.a #访问标签a
soup.a.name #访问标签a的名字
soup.a.attrs  #访问标签a的属性type为dict

#下行遍历
soup.contents #返回所有子节点
soup.body.content#返回body下的子节点
soup.head#返回head
len(soup.body.content)#返回body下的子节点个数
soup.body.content[1]#返回body下第一个子标签
for child in soup.body.children:#遍历儿子节点

#上行遍历:
for parent in soup.a.parents:#遍历了a标签的父节点

#平行遍历:
soup.a.next_sibling #返回下一个平行标签
soup.a.next_siblings #返回后续所有平行标签
soup.a.previous_sibling #返回上一个平行标签

#bs4的查找方法
soup.find_all(‘标签名称’)
soup.find_all("p","course")#可添加属性检索,更加精准
soup.find('标签名称')#找到第一个,非全部

一个例子:中国大学排名爬取

没搞懂排版的我只能一个标签一个标签地爬…
这里就只放上爬大学名称的code

import requests
from bs4 import BeautifulSoup
import bs4
headers = {
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.169 Safari/537.36"}
url='http://www.zuihaodaxue.cn/zuihaodaxuepaiming2019.html'
res=requests.get(url,headers=headers)
res.encoding=res.apparent_encoding#出现乱码的处理
text=res.text
soup=BeautifulSoup(text,"lxml")#把text建立成一个soup类型对象
items=soup.find("tbody")#找到第一个tbody,里面是所有学校的信息
fenlei=items.find_all("tr",{"class":"alt"})#找到items里面所有具备class:alt特征的标签,相当于把每个学校类拿出来变成一个list
#print(a.prettify())#美化只能对一个子节点去美化,该功能可让一个子节点内部的同级节点分段表示
for a in fenlei:
    div=a.find("div",{"align":"left"})#用循环依次从每个学校中取出标签为div,具备align:left特征的内容,这里就是学校名称。
 print(div.text)#加.text功能就使div变成str,print之后不会有标签出现

正则表达式

搜索动态文本。
同时查找或替换一组字符串
匹配字符串的全部或部分(主要)

淘宝商品比价定向爬虫

其实没有理解地很好,先放代码,明天再仔细康康

import requests
import re
#库库库
def getHTMLText(url):
    """
    请求获取html,(字符串)
    :param url: 爬取网址
    :return: 字符串
    """
    try:
        # 添加头信息,
        kv = {
            'cookie': 'thw=cn; v=0; t=ab66dffdedcb481f77fd563809639584; cookie2=1f14e41c704ef58f8b66ff509d0d122e; _tb_token_=5e6bed8635536; cna=fGOnFZvieDECAXWIVi96eKju; unb=1864721683; sg=%E4%B8%8B3f; _l_g_=Ug%3D%3D; skt=83871ef3b7a49a0f; cookie1=BqeGegkL%2BLUif2jpoUcc6t6Ogy0RFtJuYXR4VHB7W0A%3D; csg=3f233d33; uc3=vt3=F8dBy3%2F50cpZbAursCI%3D&id2=UondEBnuqeCnfA%3D%3D&nk2=u%2F5wdRaOPk21wDx%2F&lg2=VFC%2FuZ9ayeYq2g%3D%3D; existShop=MTU2MjUyMzkyMw%3D%3D; tracknick=%5Cu4E36%5Cu541B%5Cu4E34%5Cu4E3F%5Cu5929%5Cu4E0B; lgc=%5Cu4E36%5Cu541B%5Cu4E34%5Cu4E3F%5Cu5929%5Cu4E0B; _cc_=WqG3DMC9EA%3D%3D; dnk=%5Cu4E36%5Cu541B%5Cu4E34%5Cu4E3F%5Cu5929%5Cu4E0B; _nk_=%5Cu4E36%5Cu541B%5Cu4E34%5Cu4E3F%5Cu5929%5Cu4E0B; cookie17=UondEBnuqeCnfA%3D%3D; tg=0; enc=2GbbFv3joWCJmxVZNFLPuxUUDA7QTpES2D5NF0D6T1EIvSUqKbx15CNrsn7nR9g%2Fz8gPUYbZEI95bhHG8M9pwA%3D%3D; hng=CN%7Czh-CN%7CCNY%7C156; mt=ci=32_1; alitrackid=www.taobao.com; lastalitrackid=www.taobao.com; swfstore=97213; x=e%3D1%26p%3D*%26s%3D0%26c%3D0%26f%3D0%26g%3D0%26t%3D0%26__ll%3D-1%26_ato%3D0; uc1=cookie16=UtASsssmPlP%2Ff1IHDsDaPRu%2BPw%3D%3D&cookie21=UIHiLt3xThH8t7YQouiW&cookie15=URm48syIIVrSKA%3D%3D&existShop=false&pas=0&cookie14=UoTaGqj%2FcX1yKw%3D%3D&tag=8&lng=zh_CN; JSESSIONID=A502D8EDDCE7B58F15F170380A767027; isg=BMnJJFqj8FrUHowu4yKyNXcd2PXjvpa98f4aQWs-RbDvsunEs2bNGLfj8BYE6lWA; l=cBTDZx2mqxnxDRr0BOCanurza77OSIRYYuPzaNbMi_5dd6T114_OkmrjfF96VjWdO2LB4G2npwJ9-etkZ1QoqpJRWkvP.; whl=-1%260%260%261562528831082',
            'user-agent': 'Mozilla/5.0'
        }
        r = requests.get(url, timeout=30, headers=kv)
        # r = requests.get(url, timeout=30)
        # print(r.status_code)
        r.raise_for_status()
        r.encoding = r.apparent_encoding
        return r.text
    except:
        return "爬取失败"
#提取待爬取页面信息,r.raise_for_status()方法内部判断r.status_code是否等于200不需要增加额外的if语句,该语句便于利用try-except进行异常处理。
def parsePage(glist, html):
    '''
    解析网页,搜索需要的信息
    :param glist: 列表作为存储容器
    :param html: 由getHTMLText()得到的
    :return: 商品信息的列表
    '''
    try:
        # 使用正则表达式提取信息
        #商品价格
        price_list = re.findall(r'', html)
        #商品名称
        name_list = re.findall(r'', html)
        for i in range(len(price_list)):
            price = eval(price_list[i].split(":")[1])  #eval()在此可以去掉""
            name = eval(name_list[i].split(":")[1])
            glist.append([price, name])
    except:
        print("解析失败")
#提取页面中需要的信息
def printGoodList(glist):
    tplt = "{0:^4}\t{1:^6}\t{2:^10}"
    print(tplt.format("序号", "商品价格", "商品名称"))
    count = 0
    for g in glist:
        count = count + 1
        print(tplt.format(count, g[0], g[1]))
#调整页面输出的格式

#根据页面url的变化寻找规律,构建爬取url
goods_name = "书包"  # 搜索商品类型
start_url = "https://s.taobao.com/search?q=" + goods_name
info_list = []
page = 3  # 爬取页面数量

count = 0
for i in range(page):
    count += 1
    try:
        url = start_url + "&s=" + str(44 * i)
        html = getHTMLText(url)  # 爬取url
        parsePage(info_list, html) #解析HTML和爬取内容
        print("\r爬取页面当前进度: {:.2f}%".format(count * 100 / page), end="")  # 显示进度条
    except:
        continue

End 今天来不及学会正则表达式了…为今天没学习完白天还摸鱼打了两把王者而深深忏悔…五百斤的胖子说明天会更难,我流泪了…我挺好的…就是头有点冷…

PS:立flag,明天一定MOOC视频学习呜呜呜

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值