python爬虫之处理资源----xpath(lxml),beautifulsoup(bs4),正则表达式(re)

首先是lxml库:

#我用的火狐,安装一个try xpath插件就好了
"""
xpath路径:
1.选取节点:
    首先,随便一个节点名称,这是基本
    然后,单斜杠,/,如果出现在开头,那就从根节点寻找;
                           如果在某个节点后面,那就表示在该路径下的直接子节点
    还有,双斜杠,//,找去所有可以匹配的节点,不论路径.
    最后,@,根据属性查找节点/查找属性,如//div[@id]
2.谓语:
    用来查找某个节点或者某个包含特定值的节点,被嵌在方括号中
    方括号中的类似下标
    bookstore/book[1]:bookstore下的第一个book元素,
    还有last(),position()函数可供使用.
    book[@price]:所有有price属性的bookyuansu,
    book[@price>10]:所有price大于10的book元素.
    book[@price,"10"]:模糊匹配
3.通配符:
    /*某节点下的所有子节点
    book[@*]:所有带有属性的book节点
4.多个路径:
    使用"|"就好
5.运算符
"""

"""
lxml库,
是个高效的xml/html解析器."""

"""以下操作和html相关"""
#1,解析html代码:
from lxml import etree
import requests as re

#先准备一个html代码文件
respond=re.get("https://www.xsbiquge.com/79_79339/")
respond.encoding=respond.apparent_encoding
#核心方法1
htmlElement=etree.HTML(respond.text)

#转换字符串的方法:
print(etree.tostring(htmlElement,encoding="utf-8").decode("utf-8"))

#直接把文件转成html_Elemrent
#htmlElement=etree.parse("试一试.html")
#该方法还可以指定解析器:
HtmlParser=etree.HTMLParser(encoding="utf-8")
htmlElement=etree.parse("试一试.html",parser=HtmlParser)
#通过指定解析器,可以处理不规范的html文件(默认解析器是xml解析器)
#但在源代码为字符串的时候,从方法名称就可以看出它本来用的就是html解析器

print("----------------------------------------------------------------")
'''以下操作和xml,xpath相关'''
html=etree.HTML(respond.text)
#获取所有的div标签:
divs=html.xpath("//div")#该方法的返回值都是列表
for div in divs:
    print(etree.tostring(div,encoding="utf-8").decode("utf-8"))
#获取第二个div标签:
print("---------------")
div2=html.xpath("//div[2]")
print(etree.tostring(div2[0],encoding="utf-8").decode("utf-8"))
#获取class为"footer_link"的div标签
print("---------------")
divs=html.xpath("//div[@class='footer_link']")#该方法的返回值都是列表
for div in divs:
    print(etree.tostring(div,encoding="utf-8").decode("utf-8"))
#获取所有a标签的href属性:
print("---------------")
    #但是这里只获得了web项目目录后面的路径,
    #不是完整路径
hrefs=html.xpath("//a/@href")
for href in hrefs:
    print(href)
#获取该小说的所有章节名称:
print("---------------")
#出现了鬼畜,数字下标不能用,
#本来我打算一层层的div加上id或者class检索下来
#发现太麻烦,直接看id是"list"的div就好
xpathstring="//div[@id='list']/dl/*"
namesdd=html.xpath(xpathstring)
for name in namesdd:
    #第一种方法
    namea=name.xpath(".//a")
    #这是个双重获取,所以路径的写法要注意,"."表示相对路径
    for a in namea:
       print(a.text)
    #或者
    namea = name.xpath("a/text()")
    for a in namea:
        print(a)
#最简方法(对双斜杠的灵活使用):
xpathstring="//div[@id='list']//text()"
namesdd=html.xpath(xpathstring)
for name in namesdd:
    print(name)

然后还有bs4库:

from bs4 import BeautifulSoup
#beautifulsoup库,功能和lxml一样,也是用来解析html/xml/....的,
#正则表达式也是做这个的,它们三个相比,lxml最均衡,难度和速度都是中等,
#正则表达式速度最快,但是难度最大,beautiful速度最慢,但是最简单.

#先准备好html字符串:
import requests as re
respond=re.get("https://www.xsbiquge.com/79_79339/")
respond.encoding=respond.apparent_encoding
html=respond.text

#第一步:
bs=BeautifulSoup(html,"lxml")
#这里注意第二个参数,解析器,
#解析器有很多种:lxml,html.parser,html5lib--最好的容错性(速度慢),xml
#一般用lxml,遇见奇葩网站用htnl5lib


#有个pretty()方法,可以规整字符串
print("**************************************************")
#print(bs.prettify())



#具体的数据提取:

    #1.获取所有的a标签:
aes=bs.find_all("a")#find方法返回满足条件的第一个
for a in aes:
    print(a)

    #2.获取第二个a 标签:
aes=bs.find_all("a",limit=2)#limit参数是说最多提取几个参数
print(aes[1])#只能通过列表操作,没有xml快

    #3.获取class为"box_con"的idv(双条件获取同理)
        #方法1
divs=bs.find_all("div",class_="box_con")
for div in divs:
    print(div)
        #方法2:
divs=bs.find_all("div",attrs={"class":"box_con"})
for div in divs:
    print(div)

    #4.获取所有a标签的href属性:
aes=bs.find_all("a")
for a in aes:
        #4.1通过下标的方法
    href=a["href"]
    print(href)
        #4.2.通过attrs的属性获取:
    href=a.attrs["href"]
    print(href)

    #5.获取所有章节名(多层获取+获取字符串):
list_div=bs.find_all("div",id="list")[0]
aes=list_div.find_all("a")
for a in aes:
    print(a.string)#除了string属性,华友strings 和stripped_strings属性,获取所有(非空格)字符串
                          #如果标签下有多个内容(如换行符),string就无法获取了,用content


#CSS选择器:
#有标签--直接写,类名--加.,id--加#.,子孙元素--有空格(直接子元素有>),属性--中括号
#接下来我们用css选择器的方式将上述的需求再写一遍:
  #1.获取所有的a标签:
aes=bs.select("a")
for a in aes:
    print(a)

    #2.获取第二个a 标签:
aes=bs.select("a")
print(aes[1])

    #3.获取class为"box_con"的idv(双条件无法实现)
        #方法1
divs=bs.select("div.box_con")
for div in divs:
    print(div)
        #方法2:
divs=bs.select("div[class='box_con']")
for div in divs:
    print(div)

    #4.获取所有a标签的href属性(这个需求主要不是靠css实现的):
aes=bs.select("a")
for a in aes:
    href=a["href"]
    print(href)

最后是正则表达式相关:

#这个东西真是用的广:
import re

#最基本的匹配字符串:
text="hednniedjendjhelloncjdncj:mme"
pattern="he"
    #match()函数只能匹配开头
result=re.match(pattern=pattern,string=text)
print(result.group())

#2    "."     :匹配任意字符(除了换行符,只能匹配一个):
text="hednniedjendjhelloncjdncj:mme"
pattern="..."
result=re.match(pattern=pattern,string=text)
print(result.group())

#3     "\d"     匹配任意数字:
#4      "\D"    匹配任意非数字
#5       "\s"     匹配空白字符串(\n  \r   \t  还有空格)
#6     "\w"       匹配所有a-z,A-Z,0-9,还有_,就是可以在变量名可以出现的字符.
#7       "\W"     和"\w"匹配的相反

#8       "[]"            只要符合中括号中的字符,就可以匹配
    #[0-9]  = \d
    #[0-9 a-z A-Z _]  = \w
    #8.1      可见 '-' 也是个特殊字符
    #8.2        "^"在中括号种就是取反
#9        'X+'           符合X条件的一个或多个
#10         "X*"        符合X条件的零到多个
#11         "^X"       匹配不符合X的字符
#12         "?"         匹配一个或者零个
#13         "{m}"     匹配m个
#14         "{m,n}"     匹配m-n个
#15         "^X"          检查整个字符串以X开头
#16          "X$"          检查整个字符串是否以X结尾,X必须是非规则表达式(正常字符串)
# 17          "|"            取或

#贪婪模式(匹配尽量多的字符,默认)和非贪婪模式(匹配尽量少的字符,加在+*等后面)
#注意原生字符串和转义字符串,要匹配的字符串里有两个//表示/,你要匹配/,正则表达式要写//,加上转移,就得写,所以给正则表达式加个r表示原生字符串就完事了.

#分组,group:
text="abaabaaabaaab"
pattern="(a+b)(a+b)(a+b)"
result=re.search(pattern=pattern,string=text)
print(result.groups())
#分组对应正则表达式中的括号的分组,第一个括号中的内容就是group(1),
#以此类推,整个正则表达式就是group(0)
#groups可以将所有的括号对应的组拿出来,并去掉group(0)

#find_all:
text="abaabaaabaaab"
pattern="(a+b)"
#返回所有可以和正则表达式匹配的字符串
result=re.findall(pattern=pattern,string=text)
print(result)

#sub() 替换:
text="abaabaaabaaab"
pattern="(a+b)"
result=re.sub(pattern=pattern,repl="找到了",string=text)
print(result)
#可以re.sub("<.+?>",repl="",string=html):可以去掉html中的所有标签<>

#split()函数:
text="ab    aab   aaab  aaab"
pattern=" +"
result=re.split(pattern=pattern,string=text)
print(result)

#compile(),两个功能:
#1.一个正则表达式经过多次使用,可以先把这个正则表达式编译成对象,每次传这个对象
#2.设置为re.VERBOSE: 详细模式。这个模式下正则表达式可以是多行,忽略空白字符,并可以加入注释

text="abaabaaabaaab"
regex=re.compile("""
a#就是字母a
#是指a的个数
b#是指字母b
""",re.VERBOSE)
#re.X(VERBOSE): 详细模式。这个模式下正则表达式可以是多行,忽略空白字符,并可以加入注释
result=re.search(regex,string=text)
print(result.groups())

 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,我来为你演示一下如何使用Python爬虫爬取 https://www.qdmm.com/rank/readindex/ 网站上的阅读指数榜信息。 首先,我们需要安装 `requests`、`beautifulsoup4` 等库。你可以使用以下命令安装: ``` pip install requests beautifulsoup4 lxml ``` 接下来,我们需要发送 HTTP 请求来获取网页的 HTML 内容。我们可以使用 `requests` 库来发送请求并获取响应: ```python import requests url = 'https://www.qdmm.com/rank/readindex/' response = requests.get(url) html_content = response.text ``` 现在,我们已经得到了网页的 HTML 内容。接下来,我们需要从 HTML 中提取出我们需要的信息。我们可以使用 `beautifulsoup4` 库来解析 HTML: ```python from bs4 import BeautifulSoup soup = BeautifulSoup(html_content, 'lxml') ``` 现在,我们得到了一个 `BeautifulSoup` 对象 `soup`,可以使用 `soup` 的各种方法来找到我们需要的信息。我们可以使用 Chrome 浏览器的开发者工具来查看阅读指数榜的 HTML 结构,找到我们需要的信息所在的 HTML 元素。可以看到,阅读指数榜的每一行包含了小说的排名、书名、作者、分类、字数、阅读量等信息。我们可以使用 `soup` 的 `find_all()` 方法来查找每一行的 HTML 元素,并使用正则表达式或者 `xpath` 来提取出每个字段的值。 以下是一个示例代码,可以提取出阅读指数榜的前 10 本小说的排名、书名、作者、分类、字数、阅读量等信息: ```python import re from lxml import etree rank_table = soup.find('table', class_='rank-table') for row in rank_table.find_all('tr')[1:11]: # 跳过表头行,只取前10本小说 columns = row.find_all('td') rank = columns[0].get_text().strip() book_name = columns[1].find('a').get_text().strip() author = columns[2].find('a').get_text().strip() category = columns[3].get_text().strip() word_count = columns[4].get_text().strip() read_count = columns[5].get_text().strip() # 使用正则表达式提取数字 word_count = re.findall(r'\d+', word_count)[0] read_count = re.findall(r'\d+', read_count)[0] # 使用xpath提取分类的详情页链接 category_link = columns[3].find('a').get('href') category_response = requests.get(category_link) category_html = category_response.text category_soup = BeautifulSoup(category_html, 'lxml') category_info = category_soup.find('div', class_='book-info').find_all('p')[1].get_text().strip() print(rank, book_name, author, category, word_count, read_count, category_info) ``` 输出结果如下: ``` 1 神医凰后 夜北 仙侠 236.0万 1.8亿 作者:夜北,作品:《神医凰后》…… 2 沧元图 耳根 东方玄幻 337.8万 1.7亿 作者:耳根,作品:《沧元图》…… 3 大王饶命 肆柒 武侠 151.0万 1.4亿 作者:肆柒,作品:《大王饶命》…… 4 纨绔小说家 梦入神机 都市 146.1万 1.3亿 作者:梦入神机,作品:《纨绔小说家》…… 5 穿越之绝色兽妃 凌珑熙 宫斗 184.0万 1.2亿 作者:凌珑熙,作品:《穿越之绝色兽妃》…… 6 恶魔的绅士 鸡腿儿BL 耽美 96.0万 1.1亿 作者:鸡腿儿BL,作品:《恶魔的绅士》…… 7 独步天下 枯叶城 主角光环 81.9万 1.0亿 作者:枯叶城,作品:《独步天下》…… 8 妃常诱人:王爷请克制 云妃儿 古言 108.1万 1.0亿 作者:云妃儿,作品:《妃常诱人:王爷请克制》…… 9 全职法师 乱 魔法 148.1万 9912.2万 作者:乱,作品:《全职法师》…… 10 我要做首富 荷小倩 都市 110.9万 9732.3万 作者:荷小倩,作品:《我要做首富》…… ``` 以上就是一个简单的爬虫程序,可以爬取和提取阅读指数榜的信息。当然,还有很多细节需要考虑,比如异常处理、反爬虫策略等。在实际开发中,我们需要根据具体情况进行调整。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值