re、bs4、xpath的基本使用学习笔记

磊落不羁 by:磊落不羁 分类:爬虫 时间:2年前 阅读:59 评论:0

1、re的主要函数及使用

#findall  :匹配字符串中所有的符合正则的内容

re.findall()    #参数 正则  待处理文本    返回的值是list  正则前面加上r 更好

例如 :

re.findall(r"\d","ddddddddd")

#finditer:匹配字符串中所有的内容【返回的是迭代器】

it=re.finditer(r"\d","我的电话号码是111111,我女朋友的电话是:2222")
print(it)
for i in it:
    print(i.group())  #通过group函数拿到匹配到的迭代器的内容


#search() 返回的结果迭代器 拿数据依然是group()全文检索反馈第一个匹配到的结果
it=re.search(r"\d","我的电话号码是111111,我女朋友的电话是:2222")
print(it.group())
#match  match是从头开始匹配 严格匹配模式 返回迭代器
it=re.match(r"\d","我的电话号码是111111,我女朋友的电话是:2222")
print(it.group())


#预加载正则表达式
obj=re.compile(r"\d+",re.S) #re.S 让.能够匹配换行符 
然后使用下方使用
obj.findall()
obj.finditer("我的电话号码是111111,我女朋友的电话是:2222")


#(?p<组名>.*?)用来获取想获取的内容组
obj = re.compile(r"<div class='.*?'><span id='\d+'>(?P<wahaha>.*?)</span></div>",re.S)
result=obj.finditer(s)
for it in result:
   print(it.group("wahah")
#  ?P<wahaha>指的是将后边匹配的内容放到wahaha这个组中,调用方式为print(it.group(组名))


#获取组后写入字典   
dic=it.groupdict()   
dic['year']=dic['year'].strip()


#csv写入
import csv
f=open("date.csv","w")
csvwriter=f.writer(f)
csvwriter.writerow(dic.value)

#获取网址https 取消安全验证 在requests增加参数 verify=False 去掉安全验证

整体教案

import re
# findall:  匹配字符串中所有的符合正则的内容
lst = re.findall(r"\d+", "我的电话号是:10086, 我女朋友的电话是:10010")
print(lst)

# finditer: 匹配字符串中所有的内容[返回的是迭代器], 从迭代器中拿到内容需要.group()
it = re.finditer(r"\d+", "我的电话号是:10086, 我女朋友的电话是:10010")
for i in it:
    print(i.group())

# search, 找到一个结果就返回, 返回的结果是match对象. 拿数据需要.group()
s = re.search(r"\d+", "我的电话号是:10086, 我女朋友的电话是:10010")
print(s.group())


# match是从头开始匹配
s = re.match(r"\d+", "10086, 我女朋友的电话是:10010")
print(s.group())

# 预加载正则表达式
obj = re.compile(r"\d+")

ret = obj.finditer("我的电话号是:10086, 我女朋友的电话是:10010")
for it in ret:
    print(it.group())

ret = obj.findall("呵呵哒, 我就不信你不换我1000000000")
print(ret)

s = """
<div class='jay'><span id='1'>郭麒麟</span></div>
<div class='jj'><span id='2'>宋铁</span></div>
<div class='jolin'><span id='3'>大聪明</span></div>
<div class='sylar'><span id='4'>范思哲</span></div>
<div class='tory'><span id='5'>胡说八道</span></div>
"""

# (?P<分组名字>正则) 可以单独从正则匹配的内容中进一步提取内容
obj = re.compile(r"<div class='.*?'><span id='(?P<id>\d+)'>(?P<wahaha>.*?)</span></div>", re.S)  # re.S: 让.能匹配换行符

result = obj.finditer(s)
for it in result:
    print(it.group("wahaha"))
    print(it.group("id"))

re使用案例 一

# 1. 定位到2020必看片
# 2. 从2020必看片中提取到子页面的链接地址
# 3. 请求子页面的链接地址. 拿到我们想要的下载地址....
import requests
import re
domain = "https://www.dytt89.com/"
resp = requests.get(domain, verify=False)  # verify=False 去掉安全验证
resp.encoding = 'gb2312'  # 指定字符集
# print(resp.text)
# 拿到ul里面的li
obj1 = re.compile(r"2020必看热片.*?<ul>(?P<ul>.*?)</ul>", re.S)
obj2 = re.compile(r"<a href='(?P<href>.*?)'", re.S)
obj3 = re.compile(r'◎片  名(?P<movie>.*?)<br />.*?<td '
                  r'style="WORD-WRAP: break-word" bgcolor="#fdfddf"><a href="(?P<download>.*?)">', re.S)
result1 = obj1.finditer(resp.text)
child_href_list = []
for it in result1:
    ul = it.group('ul')
    # 提取子页面链接:
    result2 = obj2.finditer(ul)
    for itt in result2:
        # 拼接子页面的url地址:  域名 + 子页面地址
        child_href = domain + itt.group('href').strip("/")
        child_href_list.append(child_href)  # 把子页面链接保存起来
# 提取子页面内容
for href in child_href_list:
    child_resp = requests.get(href, verify=False)
    child_resp.encoding = 'gb2312'
    result3 = obj3.search(child_resp.text)
    print(result3.group("movie"))
    print(result3.group("download"))
    # break  # 测试用

re使用案例二

# 拿到页面源代码.   requests
# 通过re来提取想要的有效信息  re
import requests
import re
import csv

url = "https://movie.douban.com/top250"
headers = {
    "user-agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.192 Safari/537.36"
}
resp = requests.get(url, headers=headers)
page_content = resp.text

# 解析数据
obj = re.compile(r'<li>.*?<div class="item">.*?<span class="title">(?P<name>.*?)'
                 r'</span>.*?<p class="">.*?<br>(?P<year>.*?)&nbsp.*?<span '
                 r'class="rating_num" property="v:average">(?P<score>.*?)</span>.*?'
                 r'<span>(?P<num>.*?)人评价</span>', re.S)
# 开始匹配
result = obj.finditer(page_content)
f = open("data.csv", mode="w")
csvwriter = csv.writer(f)
for it in result:
    # print(it.group("name"))
    # print(it.group("score"))
    # print(it.group("num"))
    # print(it.group("year").strip())
    dic = it.groupdict()
    dic['year'] = dic['year'].strip()
    csvwriter.writerow(dic.values())

f.close()
print("over!")


2、BS4主要函数及使用

bs4 主要使用的函数 有
find
findall
get
一个案例
from bs4 import BeautifulSoup
soup=BeautifulSoup(html,"html.parser")
html=soup.find(标签,属性)

text=html.get("href") 获取标签内的内容

教案

# 安装
# pip install bs4 -i 清华
# 1. 拿到页面源代码
# 2. 使用bs4进行解析. 拿到数据
import requests
from bs4 import BeautifulSoup
import csv

url = "http://www.xinfadi.com.cn/marketanalysis/0/list/1.shtml"
resp = requests.get(url)

f = open("菜价.csv", mode="w")
csvwriter = csv.writer(f)

# 解析数据
# 1. 把页面源代码交给BeautifulSoup进行处理, 生成bs对象
page = BeautifulSoup(resp.text, "html.parser")  # 指定html解析器
# 2. 从bs对象中查找数据
# find(标签, 属性=值)
# find_all(标签, 属性=值)
# table = page.find("table", class_="hq_table")  # class是python的关键字
table = page.find("table", attrs={"class": "hq_table"})  # 和上一行是一个意思. 此时可以避免class
# 拿到所有数据行
trs = table.find_all("tr")[1:]
for tr in trs:  # 每一行
    tds = tr.find_all("td")  # 拿到每行中的所有td
    name = tds[0].text  # .text 表示拿到被标签标记的内容
    low = tds[1].text  # .text 表示拿到被标签标记的内容
    avg = tds[2].text  # .text 表示拿到被标签标记的内容
    high = tds[3].text  # .text 表示拿到被标签标记的内容
    gui = tds[4].text  # .text 表示拿到被标签标记的内容
    kind = tds[5].text  # .text 表示拿到被标签标记的内容
    date = tds[6].text  # .text 表示拿到被标签标记的内容
    csvwriter.writerow([name, low, avg, high, gui, kind, date])
f.close()
print("over1!!!!")

bs案例使用

# 1.拿到主页面的源代码. 然后提取到子页面的链接地址, href
# 2.通过href拿到子页面的内容. 从子页面中找到图片的下载地址 img -> src
# 3.下载图片
import requests
from bs4 import BeautifulSoup
import time

url = "https://www.umei.cc/bizhitupian/weimeibizhi/"
resp = requests.get(url)
resp.encoding = 'utf-8'  # 处理乱码

# print(resp.text)
# 把源代码交给bs
main_page = BeautifulSoup(resp.text, "html.parser")
alist = main_page.find("div", class_="TypeList").find_all("a")
# print(alist)
for a in alist:
    href = a.get('href')  # 直接通过get就可以拿到属性的值
    # 拿到子页面的源代码
    child_page_resp = requests.get(href)
    child_page_resp.encoding = 'utf-8'
    child_page_text = child_page_resp.text
    # 从子页面中拿到图片的下载路径
    child_page = BeautifulSoup(child_page_text, "html.parser")
    p = child_page.find("p", align="center")
    img = p.find("img")
    src = img.get("src")
    # 下载图片
    img_resp = requests.get(src)
    # img_resp.content  # 这里拿到的是字节
    img_name = src.split("/")[-1]  # 拿到url中的最后一个/以后的内容
    with open("img/"+img_name, mode="wb") as f:
        f.write(img_resp.content)  # 图片内容写入文件

    print("over!!!", img_name)
    time.sleep(1)

print("all over!!!")


3、Xpath主要函数及使用


from lxml import etree
tree=etree.parse(url) #获取内容
tree=etree.xml(xml)
tree=etree.HTML(html) #网页内容
 result=tree.xpath("/book")  #/表示层级关系,第一个/是根节点
result=tree.xpath("/book/name/text()")  #text()拿文本  返回是列表 如果放两个//则去后代所有内容    放标签  *则是通配符 忽略本级标签
result=tree.xpath("/htmL/body/uL/Li[1]/a/text()")#xpath的顺序是从l开始数的
result=tree.xpath("/html/body/ol/li/a[@href='dapao']/text()") @按照属性筛选 
for li in list:
#从每一个11中提取到文字信息
li.xpath("./a/text()")#在Li中继续去寻找。相对查找 /前加.号
result2=li.xpath("./a/@href")#拿到属性值:@属性
print(tree.xpath("/html/body/ul/li/a/@href")) 拿到节点下所有属性值到列表

 教案

# xpath 是在XML文档中搜索内容的一门语言
# html是xml的一个子集
"""
<book>
    <id>1</id>
    <name>野花遍地香</name>
    <price>1.23</price>
    <author>
        <nick>周大强</nick>
        <nick>周芷若</nick>
    </author>
</book>
"""
# 安装lxml模块
# pip install lxml -i xxxxxx
# xpath解析
from lxml import etree

xml = """
<book>
    <id>1</id>
    <name>野花遍地香</name>
    <price>1.23</price>
    <nick>臭豆腐</nick>
    <author>
        <nick id="10086">周大强</nick>
        <nick id="10010">周芷若</nick>
        <nick class="joy">周杰伦</nick>
        <nick class="jolin">蔡依林</nick>
        <div>
            <nick>热热热热热1</nick>
        </div>
        <span>
            <nick>热热热热热2</nick>
        </span>
    </author>

    <partner>
        <nick id="ppc">胖胖陈</nick>
        <nick id="ppbc">胖胖不陈</nick>
    </partner>
</book>
"""

tree = etree.XML(xml)
# result = tree.xpath("/book")  # /表示层级关系. 第一个/是根节点
# result = tree.xpath("/book/name")
# result = tree.xpath("/book/name/text()")  # text() 拿文本
# result = tree.xpath("/book/author//nick/text()")  # // 后代
# result = tree.xpath("/book/author/*/nick/text()")  # * 任意的节点. 通配符(会儿)
result = tree.xpath("/book//nick/text()")
print(result)


教案二

from lxml import etree


tree = etree.parse("b.html")
# result = tree.xpath('/html')
# result = tree.xpath("/html/body/ul/li/a/text()")
# result = tree.xpath("/html/body/ul/li[1]/a/text()")  # xpath的顺序是从1开始数的, []表示索引

# result = tree.xpath("/html/body/ol/li/a[@href='dapao']/text()")  # [@xxx=xxx] 属性的筛选

# print(result)

# ol_li_list = tree.xpath("/html/body/ol/li")
#
# for li in ol_li_list:
#     # 从每一个li中提取到文字信息
#     result = li.xpath("./a/text()")  # 在li中继续去寻找. 相对查找
#     print(result)
#     result2 = li.xpath("./a/@href")  # 拿到属性值: @属性
#     print(result2)
#
# print(tree.xpath("/html/body/ul/li/a/@href"))

print(tree.xpath('/html/body/div[1]/text()'))
print(tree.xpath('/html/body/ol/li/a/text()'))


xpath案例

# 拿到页面源代码
# 提取和解析数据
import requests
from lxml import etree

url = "https://beijing.zbj.com/search/f/?type=new&kw=saas"
resp = requests.get(url)
# print(resp.text)

# 解析
html = etree.HTML(resp.text)

# 拿到每一个服务商的div
divs = html.xpath("/html/body/div[6]/div/div/div[2]/div[4]/div[1]/div")
for div in divs:  # 每一个服务商信息
    price = div.xpath("./div/div/a[1]/div[2]/div[1]/span[1]/text()")[0].strip("¥")
    title = "saas".join(div.xpath("./div/div/a[1]/div[2]/div[2]/p/text()"))
    com_name = div.xpath("./div/div/a[2]/div[1]/p/text()")[0]
    location = div.xpath("./div/div/a[2]/div[1]/div/span/text()")[0]
    print(com_name)


非特殊说明,本文版权归原作者所有,转载请注明出处

本文地址:http://php.liulei.com.cn/?type=acticle&id=25

评论列表

发表评论

  • 昵称(必填)
  • 邮箱
  • 网址

TOP