爬虫辅助技术(css选择器、xpath、正则基础语法)

一、css选择器

css基础语法

学习网站:CSS 选择器 | 菜鸟教程

|------------------|---------------------|
| 语法 | 功能 |
| p | 选择p标签 |
| .class1 | 选择class="class1"的标签 |
| #id1 | 选择id="id1"的标签 |
| body p | 选择body标签下的所有p标签 |
| body>p | 选择body标签下子级p标签 |
| div,p | 选择p和div标签 |
| div+p | 选择和div挨着的p标签 |
| [class] | 选择有class属性的标签 |
| [class=class1] | 选择class="class1"的标签 |

实现代码(python)

python 复制代码
pass

二、Xpath

基础语法

学习网站:XPath 教程 | 菜鸟教程

xpath中将标签称为节点

|----------------|-----------------------------|
| 语法 | 功能 |
| p | 选择当前节点的所有名为p的子节点 |
| / | 选择根节点,html的根节点为html标签 |
| /p | 选择根节点下子节点中的p节点 |
| //p | 选择根节点下后辈节点中的p节点,后辈包含子节点的子节点 |
| title[@lang] | 选择有lang属性的title节点 |

实现代码(python)

python 复制代码
from lxml import etree
import requests

def xpath_spider(url="https://www.test.com/fw/?k=%E7%BD%91%E7%BB%9C%E5%AE%89%E5%85%A8"):
    resp = requests.get(url)
    resp.encoding = resp.apparent_encoding
    sour = resp.text
    et = etree.HTML(sour)
    divs = et.xpath("//div[@class='search-result-list-service']/div")
    for div in divs:
        price = div.xpath("./div/div[3]/div/span/text()")[0]
        name = div.xpath("./div/div[3]/div[2]/div/span//text()")
        name = "-".join(name)
        company = div.xpath("./div/div[5]/div/div/div/text()")[0].split("丨")[0]
        
        print(f"名称:{name}\n价格:{price}\n公司:{company}\n")

if "__main__" == __name__:
    xpath_spider()

"""结果
名称:企业-网络-,服务器,存储,系统调试
价格:¥500
公司:t_9020_HBtnz8

名称:*测试,-安全-测试,app测试,-安全-检查
价格:¥1000
公司:网络安全爱好者

名称:技术服务|网站运维|数据库维护
价格:¥600
公司:宇视星AI启航

名称:提供远程技术支持服务,涵盖家庭-网络-调试、打印机配
价格:¥49
公司:t_9396_LD3bnh

名称:Web*测试基础版
价格:¥800
公司:祥安安服
.....

三、正则

基础语法

学习网站:正则表达式 -- 语法 | 菜鸟教程

语法测试网站:https://www.jyshare.com/front-end/854/

|------------------|--------------------------------------------------------|
| 语法 | 功能 |
| [ABC] | 匹配A,B,C中任意一个字符 |
| [^ABC] | 匹配除了A,B,C的任意字符 |
| [A-Z] | 匹配A-Z中一个字符 |
| . | 匹配除了空白字符的一个任意字符 |
| \s \S | \s匹配任意一个空白字符,\S匹配任意一个非空白字符 |
| \w \W | \w匹配字母、数字、下划线(变量命名字符),大写取反 |
| \d | \d匹配任意一个数字字符,大写取反 |
| ^a | 匹配作为字符串开头的a字符 |
| a$ | 匹配作为字符串结尾的a字符 |
| a* | 匹配任意个数量的a字符 |
| a+ | 匹配最少一个a字符 |
| a? | 匹配最多一个a字符 |
| a{x} | 匹配x个a字符 |
| a{x,y} | 匹配最少x个,最多y个a字符 |
| a{x,} | 匹配最少x个a字符 |
| a{,y} | 匹配最多x个a字符 |
| () | 分组符,可以理解为把括号中表达式匹配到的字符存入一个变量中可以后续调用 |
| \bcat\b | \b表示匹配一个非字母、数字下划线的字符,保证\b中间是一个独立的单词 |
| \Bcat\B | \B与\b相反,表示我要匹配一个单词中的cat字符串 |
| def(?=abc) | 表示匹配后面跟着abc字符串的def字符串 例:(defabc) |
| def(?!abc) | 表示匹配后面没有跟着abc字符串的def字符串 例:(defxxx) |
| (?<=abc)def | 匹配前面连接着一个abc字符串的def字符串 例:(abcdef) |
| (?<!abc)def | 匹配前面没有连接着一个abc字符串的def字符串 例:(xxxdef) |
| \1 | \1的作用就是调用前面分组中匹配到的字符串 例:(\w+) \1 匹配 "hello hello" |
| (?P<word>\w+) | 给分组取到的数据取名为word。可以理解为给word变量赋值。注:此为python语法,不同编程语言有所偏差 |

隐藏匹配规则贪婪:

* + {x,y} 这三个数量匹配语法都会尽可能多的匹配字符

原始字符:adcxxxxxxxxstopxxxxxxxstop

例:abc\w+stop 此表达式会匹配整条字符串

避免贪婪(懒惰匹配)

例:abc\w+?stop 匹配尽量少的字符串

实现代码(python)

python 复制代码
def request_data(movie_url):
    try:
        movie_info_pattern = re.compile(
            r"<br />◎片  名 (?P<movie_name>.*?)"
            r"<br />◎年  代 (?P<release_year>\d{4})"
            r"<br />◎产  地 (?P<production_region>.*?)"
        )
        movie_response = requests.get(url=movie_url, headers=headers, timeout=10)
        movie_response.encoding = movie_response.apparent_encoding
        movie_html = movie_response.text
        movie_info = movie_info_pattern.search(movie_html)
        return movie_info
    except Exception as e:
            print(f"处理电影页面 {movie_url} 时出错: {e}")
相关推荐
牛先森家的牛奶2 小时前
elementUI的table合并行和列模板
前端·javascript·elementui
En^_^Joy2 小时前
CSS常用属性速查手册
前端·css
Bigger2 小时前
踩坑记:NPM 发布脚本导致组件重复发布
前端·ci/cd·npm
Hao_Harrision2 小时前
50天50个小项目 (React19 + Tailwindcss V4) ✨ | AutoTextEffect(自动打字机)
前端·typescript·react·tailwindcss·vite7
IT_陈寒2 小时前
Vite 3.0 实战:5个优化技巧让你的开发效率提升50%
前端·人工智能·后端
玲小珑3 小时前
React 防抖函数中的闭包陷阱与解决方案
前端·react.js
lcc1873 小时前
CSS3 新增边框属性
css
咖啡の猫3 小时前
TypeScript编译选项
前端·javascript·typescript
想学后端的前端工程师3 小时前
【Vue3响应式原理深度解析:从Proxy到依赖收集】
前端·javascript·vue.js