爬虫基础二----数据解析

回忆往昔:

  上一篇文章学习了怎么通过request获取到网页的源代码,以便于我们从中提取想要的信息。

这篇文章就是介绍如何从中提取自己想要的信息。主要有三种方式

1.正则表达式(re)

正则表达的的基础这里就不多介绍了,介绍一下常用的方法吧

1.1 re.findall('表达式','被查找的数据'):查到所有匹配到的数据以列表的方式输出

import re
#第一种 re.findall
res = re.findall(r"\d+","我叫拉拉骆驼,今年18岁,2000年")#在正则表达式前面加上
#r是常见的转意字符方式
print(res)
#结果为['18', '2000']

1.2 re.finditer('表达式','被查找的数据'):查到所有匹配到的数据以迭代器的方式输出,需要循环取出。这里容易忘记最后需要把value用group取出

res1 = re.finditer(r"\d+","我叫拉拉骆驼,今年18岁,2000年")#得到的结果是一个迭代器,需要取出来

print(res1)
for item in res1:
    print(item)
    print(item.group())#group是将value从中取出
"""输出结果为:
<callable_iterator object at 0x00000296E6A81E20>
<re.Match object; span=(8, 10), match='18'>
18
<re.Match object; span=(12, 16), match='2000'>
2000


"""

1.3 re.search('表达式','被查找的数据'):这个返回匹配到的第一个数据,并且是以对象的形式,需要用group取出value值

res2 = re.search(r"\d+","我叫卡卡骆驼,今年18岁,2000年")#匹配到第一个后停止匹配
print(type(res2))
print(res2)
print(res2.group())
输出结果为:
<class 're.Match'>
<re.Match object; span=(8, 10), match='18'>
18

1.4 re.match('表达式','被查找的数据'):此方法只会从头开始匹配,如果匹配到了则返回值,匹配不到返回none。

res3 = re.match(r"\d+","我叫卡卡,今年18岁,2000年")#从第一个开始匹配,第一个没有没有则直接为None
print(res3)
print(res3.group())
结果为
None
Traceback (most recent call last):
  File "D:\DownloadProgram\PyCharm\PythonProject\pythonProject1\day02\gyd_re01.py", line 23, in <module>
    print(res3.group())
AttributeError: 'NoneType' object has no attribute 'group'

空值不可以获取value

最后还有一个预加载:re.compile('表达式'):可以预加载,只加载一次,有效减少内存占用。

一般先试用compile,后面再接着四种匹配方法。

import re
com = re.compile(r"\d+")#预加载正则表达式,使其不重复
d = com.finditer("我叫拉拉骆驼,今年18岁,2000年")
for i in d :
    print(i.group())
结果为
18
2000

还有两个重要的匹配:贪婪匹配和惰性匹配

贪婪匹配:.*    (.是任意,*是重复0次或者多次,所以贪婪匹配就是尽可能匹配的多)

惰性匹配:.*? (?是重复0次或一次 , 所以惰性匹配是尽可能匹配的少)

让我们来试验一下

import re

s = "我是卡卡骆驼卡卡骆驼"
t = re.findall(r'我是.*骆驼',s)
print(t)
#结果为:['我是卡卡骆驼卡卡骆驼']
t2 = re.findall(r'我是.*?骆驼',s)
print(t2)
#结果为:['我是卡卡骆驼']

简单的总结一下:正则表达式有四种常用的方法,其中findall返回的是列表,其余三种都是需要用group取value,其中第二中方法效率最高,也最常用。

compile方法可以预加载表达式,加载一次可以用多次。

两个匹配常用的是.*?

2.bs4

bs4是基于标签获取数据的

使用流程为

2.1初始化:page = beautifulsoup(被查取的数据,"html.parser")

2.2 两个方法:

dive= page.find('标签名',id= '')   只能查找到第一个,相当于re.search

dive= page.findall('标签名',id= '')   查找多个

其中标签名class比较特殊,它是python中的保留关键字,需要用字典的形式进行装备

find:

from bs4 import BeautifulSoup
import requests
#获取到页面源码
url = 'https://beijing.qianlong.com/2023/1228/8173119.shtml'
resp = requests.get(url)
resp.encoding = "utf-8"
#初始化bs4
page = BeautifulSoup(resp.text, 'html.parser')
div = page.find("div", id="contentStr")#解析到div
f = open(file="新闻.txt", mode="w", encoding="utf-8")
ps = div.find_all("p")#找到文字
for p in ps:
    p=p.text.strip()
    print(p)
    f.write(p)
f.close()#关闭
resp.close()#关闭

findall

import requests
from bs4 import BeautifulSoup
url = 'https://desk.3gbizhi.com'
#获取网页信息
response = requests.get(url)
page=response.text
#print(response.text)
#初始化bs4
soup = BeautifulSoup(page,'html.parser')
#需要注意的是,因为class是python的保留关键字,若要匹配标签内class的属性,需要特殊的方法:在attrs属性用字典的方式进行参数传递
#多个属性定位是也需要用字典的方式
a = soup.findAll('a',{'class':'desk imgw'})#class 需要用字典来装备#找到图片地址

n=1
for i in a:
    href=i.get('href')
    #print(href)
    child_page = requests.get(href)#找到子页面中的下载地址
    #print(child_page.text)
    child_soup = BeautifulSoup(child_page.text,'html.parser')
    child_soup_1 = child_soup.find("div",{'class':'img-table-cell wallphotos'})
    img = child_soup_1.find("img")
    img_url = img.get('src')
    #print(img_url)
    img = requests.get(img_url)#下载图片
    #保存图片
    with open(f'test{n}.jpg','wb') as f:#二进制需要用wb进行保存
        f.write(img.content)#content:图片需要用二进制保存
        print(f"第{n}个下载完成")
        n+=1

2.3 获取数据

获取属性值:div.get('属性')

获取文本值: div.text

总结:bs4先初始化再通过两个方法找标签,找到标签后就取文本或者属性

3.xpath

xpath是通过节点获取数据

流程:

3.1初始化(变树):tree=etree.HTML(网页源码)

3.2查找节点:

        tree.xpth(父/子/孙)

        tree.xpth(父//孙)

        tree.xpth(父/*/孙) *是整数

        tree.xpth(父/子[@id = ''])属性控制

3.3获取值/属性值

        获取文本值:tree.xpath(父/子/text()) 

        获取属性值:tree.xpath(父/子/@id)

总结:xpath与bs4的流程极为相似,获取值的方式也比较相似,先初始化,在从节点中拿值。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值