Python 爬虫笔记4

目录

正则表达式

匹配单个字符

匹配多个字符

匹配分组

电影TOP100正则爬取

jsonpath的使用

lxml模块和xpth语法学习

xpath语法

xpath语法的妙用

lxml模块的使用


正则表达式

用法: re模块 match 方法 

import re

# 使用match方法进行匹配操作
res = re.match('hello', 'hello world')

#如果上面匹配到数据的话,可以使用group方法来提取数据
print(res)
print(res.group())

除了使用match 方法,还有search方法 findall方法,sub方法 ,compile方法,用处不相同,先不举例了

匹配单个字符

.匹配任意一个字符(除了换行符‘\n’) 如果匹配‘ . ’则需要用转义字符\.来表示
[ ]匹配[ ]中列举的字符,[a-zA-Z0-9],[a-zA-Z]表示所有字母和数字
\d匹配数字0-9
\D匹配非数字,即不是数字的其他任何值
\s匹配空白,即空格或tab键
\S匹配非空白
\w匹配单词字符,即0-9,a-z,A-Z,_,中文字符等
\W匹配非单词字符

匹配多个字符

*匹配前一个字符出现0次或者无限次,即可有可无
+匹配前一个字符出现1次或者无限次,即至少有1次
?匹配前一个字符出现1次或者0次,即要么有1次,要么没有
{m}匹配前一个字符出现m次
{m,}匹配前一个字符至少出现m次
{m,n}匹配前一个字符出现从m到n

匹配分组

|匹配左右任意一个表达式
(ab)将括号中字符作为一个分组
\num引用分组num匹配到的字符串
(?P<name>)分组起别名
(?P=name)引用别名为name分组匹配到的字符串

例子很多,不码了 

 熟悉使用这些规则可以到这个网站:编程胶囊

电影TOP100正则爬取

import re
import requests

#定义一个方法获取html
def get_html(url):
    headers={
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.110 Safari/537.36'
    }
    response = requests.get(url,headers=headers)
    response.encoding="utf-8" #记得编码一下 否则乱码
    return response.text


def get_movie(html):
    #正则表达式提取 排名 名字 演员 时间
    pattern = re.compile(r'<dd>.*?board-index.*?>(\d+)</i>'
                         r'.*?title="(.*?)"'
                         r'.*?star(.*?)</p>'
                         r'.*?releasetime(.*?)</p>.*?'
                         r'</dd>', re.S)
                             #re.S用来匹配掉HTML代码中一些空格和换行符
    r= re.findall(pattern,html) #findall方法匹配一下
    
    print(r)

def main():
    url = "https://www.maoyan.com/board/4?timeStamp=1640940899645&sVersion=1&requestCode=f981fcd1f588f0956b1e65a57b93a4e0zdnzj&webdriver=false&index=6&signKey=c8cfdab2d87af2ba1ee53b09aa767f4f&channelId=40011"
    html = get_html(url)
    get_movie(html)

if __name__ == '__main__':
    main()

运行出来是空列表 ,猫眼不让爬取了

用正则感觉好难

每个电影的信息都在一个<dd>的标签里面,所以开头结尾写上这个标签

前后有一些标签符号可以用 .*? 来匹配掉, .*用来匹配所有的字符,?把贪婪状态改为非贪婪

\d+ 表示排名数字,</i>结尾

后面也是同样方法

表示不好实操,难理解

jsonpath的使用

安装jsonpath,一般直接pip install jsonpath 就行,我的依旧不行

各种问题又来了,写了一下自己的解决思路:解决办法

jsonpath 语法(一般只用 $ 和 . 和 ..)

JSONPATH说明
$文档根元素
@当前元素
.或[]匹配下级元素
··递归匹配所有子元素
*通配符,匹配下级元素
import jsonpath

data = {'key1': {'key2': {'key3': {'key4': {'key5': {'key6': 'python'}}}}}}

#用字典的key值 一个个的去取
result = data['key1']['key2']['key3']['key4']['key5']['key6']
print(result)

#用jsonpath
#第一个参数放提取的数据data,第二个参数写jsonpath的语法
#  $表示根节点 .表示从根节点开始的第一个值
print(jsonpath.jsonpath(data,'$.key1'))

#如果要拿python,用..  $..key7
print(jsonpath.jsonpath(data,'$..key6'))

lxml模块和xpth语法学习

xpath语法

常用符号

符号说明举例
/表示从root开始查找,或者表示子节点/html/body/div
//表示从任意层级开始查找//div
*通配符,表示任意元素
@获取属性//img[@alt=‘xxx’]
.当前层级或当前节点
上一层级或父节点//div/…/img

网页中的信息如下

我们想要得到Python, 看HTML代码

 XPath Helper 插件输入

//div[@class="main-content J-content"]/dl/dd/h1

 一级一级输入即能得到想要的,上面就是要学习的xpath语法

xpath语法的妙用

我们上网 “借鉴” 作文的时候,某些网站会禁止穷人复制,我们可以用xpath来 “ 学习 ”一下

直接在网页 按住shift键,XPath Helper 会自动生成对应的语法 和 内容

 XPath Helper 真的是非常地人性化啊,哈哈哈哈

lxml模块的使用

安装lxml又给自己干懵逼了,捣鼓两三个小时,解决了自己的问题

写了个解决方法

lxml 是 一个 HTML/XML 的解析器,主要的功能是如何解析和提取 HTML/XML 数

lxml 模块 实现了xpath与python爬虫的交互

from lxml import etree

text = '''
 <div> 
    <ul> 
        <li class="item-1"><a>1</a></li> 
        <li class="item-1"><a href="link2.html">2</a></li> 
        <li class="item-inactive"><a href="link3.html">3</a></li> 
        <li class="item-1"><a href="link4.html">4</a></li> 
        <li class="item-0"><a href="link5.html">5</a> 
    </ul> 
</div> '''

# 可以把text里面的内容生成一个HTML对象,相当于我们在网上拿到的HTML代码
html = etree.HTML(text)

# xpath()语法,获取上面a标签的内容 用text()
html_list = html.xpath('//a/text()')
print(html_list)

# 获取href属性后面的链接 ,获取属性用@
href_list = html.xpath('//a/@href')
print(href_list)

# 以键值对的形式输出
# 先定义一个空字典
data_dict = {}
for key in href_list:
    index = href_list.index(key)   #用index方法获取key的下标
    data_dict[key] =html_list[index]

print(data_dict)

 

因为第一个a标签没有href属性,导致kry:value值没有一一对应上

这个问题的本质就是因为href_list这个列表少一个,少一个的原因是在这个

xpath语句里面直接取了href  ‘’href_list = html.xpath('//a/@href')‘’

换个思路,不直接取herf属性,取a标签,通过a标签取键值对

#取a标签
a_list = html.xpath('//a')
print(a_list)

#写一个for循环,直接通过a来调用xpath方法
for a in a_list:
    print(a.xpath('.//text()'), a.xpath('.//@href'))
      #此时a就是根节点  .是当前节点 //是取当前节点的任意内容

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值