首页 > 编程语言 >自学Python爬虫笔记(day6)

自学Python爬虫笔记(day6)

时间:2023-04-14 16:01:36浏览次数:39  
标签:xpath Python text 爬虫 day6 html href print div

环境python3.9版本及以上,开发工具pycharm

 

XPath解析:

XPath是一门在XML文档中查找信息的语言,XPath可以用来在XML文档中对元素和属性进行遍历,而我们熟知的HTML恰巧属于XML中的一个子集,所以完全可以用XPath去查找html中的内容。

首先看:

<book>
    <id>1</id>
    <name>野花遍地香</name>
    <price>1.23</price>
    <author>
        <nick id="10086">周大强</nick>
        <nick id="10010">周芷诺</nick>
     </author>
</book>

在上述html中,book、id、name、price……都被称为节点;id、name、price、author都被称为book的子节点;book被称为id、name、price、author的父节点;id、name、price、author被称为兄弟节点。

下面通过一些例子来理解:

from lxml import etree

# 如果pycharm报错,可以考虑这种导入方式
# from lxml import html
# etree = html,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="jay">周杰伦</nick>
        <nick class="jolin">蔡依林</nick>
        <div>
            <nick>惹了</nick>
        </div>
    </author>
    <partner>
        <nick id="ppc">胖胖陈</nick>
        <nick id="ppbc">胖胖不沉</nick>
    </partner>
</book>
'''
# 此时练习只使用XML
et = etree.XML(xml)
# result = et.xpath('/book')      # / 表示根节点
# result = et.xpath('/book/name')     # 在xpath中间的/表示的是儿子
# result = et.xpath('/book/name/text()')[0]       # text() 拿文本
# result = et.xpath('/book//nick')        # // 表示的是子孙后代
# result = et.xpath('/book/*/nick/text()')        # * 通配符
# result = et.xpath('/book/author/nick[@class="jay"]/text()')     # []表示属性筛选,@属性名=值 类似bs4中find(Nick,attrs={'class': 'jay'})
result = et.xpath('/book/partner/nick/@id')     # 最后一个/表示拿到Nick里面的id的内容,@属性。可以直接拿到属性值
print(result)


# xpath处理HTML
html = '''
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8" />
    <title>Title</title>
</head>
<body>
    <ul>
        <li><a href="http://www.baidu.com">百度</a></li>
        <li><a href="http://www.google.com">谷歌</a></li>
        <li><a href="http://www.sogou.com">搜狗</a></li>
    </ul>
    <ol>
        <li><a href="feiji">飞机</a></li>
        <li><a href="dapao">大炮</a></li>
        <li><a href="huoche">火车</a></li>
    </ol>
    <div class="job">李嘉诚</div>
    <div class="common">胡辣汤</div>
</body>
</html>
'''

et = etree.HTML(html)
# li_list = et.xpath('/html/body/ul/li[2]/a/text()')
# print(li_list)

ll = et.xpath('//li')
for i in ll:
    href = i.xpath('./a/@href')[0]      # ./表示当前节点
    text = i.xpath('./a/text()')[0]     # ./表示当前节点
    print(text, href)

下面是对基础知识掌握后,跟做的一个案例:

'''
1.拿到页面源代码
2.从页面源代码中提取你需要的数据,价格,名称, 公司名称
'''
import requests
from lxml import etree

url = "https://beijing.zbj.com/search/service/?l=0&kw=saas&r=2"
resp = requests.get(url)
resp.encoding = 'utf-8'
# print(resp.text)

# 提取数据
et = etree.HTML(resp.text)
divs = et.xpath('//div[@class="service-card-wrap"]')
for div in divs:
    # 此时的div就是一条数据,对应一个商品信息
    # 商品价格
    price = div.xpath("./div/div[3]/div[1]/span/text()")
    if not price:   # 过滤无用数据
        continue
    price = price[0]
    company = div.xpath("./div/a/div[2]/div[1]/div/text()")[0]
    name = div.xpath("./div/div[3]/div[2]/a/text()")[0]
    name = ''.join(name)
    print(name+"\t", company+"\t", price+"\t")

由于现在这个界面变成了JS动态界面,我们发送一次请求只能获取到10条数据,然而在我们查看页面源代码时,发现它的HTML框架存在,数据也存在,但是是一次请求时分成多个时延发送,所以我们请求一次值获取到了第一次出现的数据,那些后面缓冲出来的数据并没有一次性爬取到,当我们把过滤无用数据这段代码去掉,就可以发现剩下的40条数据都为空,所以此次数据爬虫应当算成功!

 

PyQuery解析:

直接看代码

from pyquery import PyQuery

# html = """
#     <ul>
#         <li class="aaa"><a href="http://www.google.com">谷歌</a></li>
#         <li class="aaa"><a href="http://www.baidu.com">百度</a></li>
#         <li class="bbb" id='qq'><a href="http://www.qq.com">腾讯</a></li>
#         <li class="bbb"><a href="http://www.yuanlai.com">源来</a></li>
#     </ul>
# """

# 加载html内容
# p = PyQuery(html)

# print(p)
# print(type(p))
# pyquery对象接(css选择器)

# a = p('a')
# print(a)
# print(type(a))      # 依然是pyquery对象

# 链式操作
# a = p("li")("a")
# print(a)

# a = p("li a")
# print(a)

# a = p(".aaa a")      # class="aaa"
# print(a)

# a = p("#qq a")      #id="qq"
# print(a)

# href = p("#qq a").attr("href")  # 拿属性
# text = p("#qq a").text()    # 拿文本
# print(text)

# 坑,如果多个标签同时拿属性,只能默认拿到第一个
# href = p("li a").attr("href")
# print(href)

# 多个标签拿属性
# it = p("li a").items()
# for item in it:     # 从迭代器中拿到每一个标签
#     href = item.attr("href")    # 拿到href属性
#     text = item.text()
#     print(text, href)

# 快速总结:
# 1.pyquery(选择器)
# 2.item()  当选择器选择的内容有很多时,需要一个一个处理时‘
# 3.attr(属性名):获取属性信息
# 4.text()  获取文本


# div = '''
#     <div><span>i love you</span></div>
# '''
# p = PyQuery(div)
# html = p("div").html()  # 全都要
# text = p("div").text()  # 只要文本,所有的html标签都被过滤掉
# print(html)
# print(text)


html = '''
<HTML>
    <div class='aaa'>哒哒哒</div>
    <dic class='bbb'>嘟嘟嘟</div>
</HTML>
'''

p = PyQuery(html)

# p("div.aaa").after('''<div class='ccc'>吼吼吼</div>''')    # 在xxxx标签后面添加xxxx新标签
# p("div.aaa").append('''<span>i love you</span>''')      # 在xxxx标签中添加添加xxxx新标签
#
# p("div.bbb").attr(("class", "aaa"))     # 修改属性
# p("div.bbb").attr("id", "123456")       #新增属性,前提是该标签,没有这个属性
# p("div.bbb").remove_attr("id")      # 删除属性
# p("div.bbb").remove()       # 删除标签
# print(p)
from pyquery import PyQuery

# html = """
#     <ul>
#         <li class="aaa"><a href="http://www.google.com">谷歌</a></li>
#         <li class="aaa"><a href="http://www.baidu.com">百度</a></li>
#         <li class="bbb" id='qq'><a href="http://www.qq.com">腾讯</a></li>
#         <li class="bbb"><a href="http://www.yuanlai.com">源来</a></li>
#     </ul>
# """

# 加载html内容
# p = PyQuery(html)

# print(p)
# print(type(p))
# pyquery对象接(css选择器)

# a = p('a')
# print(a)
# print(type(a))      # 依然是pyquery对象

# 链式操作
# a = p("li")("a")
# print(a)

# a = p("li a")
# print(a)

# a = p(".aaa a")      # class="aaa"
# print(a)

# a = p("#qq a")      #id="qq"
# print(a)

# href = p("#qq a").attr("href")  # 拿属性
# text = p("#qq a").text()    # 拿文本
# print(text)

# 坑,如果多个标签同时拿属性,只能默认拿到第一个
# href = p("li a").attr("href")
# print(href)

# 多个标签拿属性
# it = p("li a").items()
# for item in it:     # 从迭代器中拿到每一个标签
#     href = item.attr("href")    # 拿到href属性
#     text = item.text()
#     print(text, href)

# 快速总结:
# 1.pyquery(选择器)
# 2.item()  当选择器选择的内容有很多时,需要一个一个处理时‘
# 3.attr(属性名):获取属性信息
# 4.text()  获取文本


# div = '''
#     <div><span>i love you</span></div>
# '''
# p = PyQuery(div)
# html = p("div").html()  # 全都要
# text = p("div").text()  # 只要文本,所有的html标签都被过滤掉
# print(html)
# print(text)


html = '''
<HTML>
    <div class='aaa'>哒哒哒</div>
    <dic class='bbb'>嘟嘟嘟</div>
</HTML>
'''

p = PyQuery(html)

# p("div.aaa").after('''<div class='ccc'>吼吼吼</div>''')    # 在xxxx标签后面添加xxxx新标签
# p("div.aaa").append('''<span>i love you</span>''')      # 在xxxx标签中添加添加xxxx新标签
#
# p("div.bbb").attr(("class", "aaa"))     # 修改属性
# p("div.bbb").attr("id", "123456")       #新增属性,前提是该标签,没有这个属性
# p("div.bbb").remove_attr("id")      # 删除属性
# p("div.bbb").remove()       # 删除标签
# print(p)

下面是跟做未成功的案例(它网站变化了,我试过自己的方式,没成功,所以就把老师的抄下来以便自己学习)

'''
1.提取页面源代码
2.解析页面源代码,提取数据
'''
import requests
from pyquery import PyQuery


def get_page_source(url):
    resp = requests.get(url)
    # resp.encoding = 'gbk'
    return resp.text

def parse_page_source(html):
    doc = PyQuery(html)
    mt_list = doc(".my-10").items()      # class="mt-10"
    for mt in mt_list:      # 拿到每一个mt

        # 判断是否有汽车经销商
        if not  mt("div > dl:nth-child(3) > dt:contains(购车经销商)"):
            mt("div > dl:nth-child(2)").after(PyQuery('''
                <dl class="choose-dl">
                    <dt>购车经销商</dt>
                    <dd>
                        <a href="###" class="js-dearname" data-val="125965,47759"
                            &nbsp
                        </a>
                    </dd>
                </dl>
            '''))       # 向 地点 后添加购车经销商进去

        # 提取购买的车型
        # 想要在已经提取的内容中获取第一个怎么办?  eq(0)
        # nth—child(1) 在css进行选择的时候,选取第一个位置的内容
        chexing = mt("div > dl:nth-child(1) > dd").eq(0).text().replace("\n", "").replace(" ", "")
        didian = mt("div > dl:nth-child(2) > dd").text()
        shijian = mt("div > dl:nth-child(4) > dd").text()
        jiage = mt("div > dl:nth-child(5) > dd").text().replace(" 万元", "")
        youhao = mt("div > dl:nth-child(6) > dd > p:nth-child(1)").text().replace(" 升/百公里", "")
        gonglishu = mt("div > dl:nth-child(6) > dd > p:nth-child(2)").text().replace(" 公里", "")
        other = mt("div > div > dl > dd").text().split()
        # 存储到文件中
        with open("A8.csv", mode="w", encoding='utf-8') as f:
            f.write(chexing,didian, shijian, jiage, youhao, gonglishu, other)
        f.close()


def main():
    url = 'https://k.autohome.com.cn/146/'
    # 1.提取页面源代码
    html = get_page_source(url)
    # 2.解析页面源代码,提取数据
    parse_page_source(html)


if __name__ == "__main__":
    main()

 

标签:xpath,Python,text,爬虫,day6,html,href,print,div
From: https://www.cnblogs.com/Hyun79/p/17318479.html

相关文章

  • 大道至简:Python奇技淫巧记录 | 语法糖分析
    目录0.内置函数enumerate1.zip妙用2.Python传参0.内置函数enumerate偶然看到别人题解中fori,iteminenumerate(arr)的写法,非常方便。在需要获取元素index而又不关心数组长度情况下,推荐这种写法,节省了两行代码!否则:n=len(arr)foriinrange(n):item=arr[i]......
  • DolphinDB +Python Airflow 高效实现数据清洗
    DolphinDB作为一款高性能时序数据库,其在实际生产环境中常有数据的清洗、装换以及加载等需求,而对于该如何结构化管理好ETL作业,Airflow提供了一种很好的思路。本篇教程为生产环境中ETL实践需求提供了一个解决方案,将PythonAirflow引入到DolphinDB的高可用集群中,通过使用A......
  • 功能不够用?使用C++编写通达信插件及接入Python(一)
    第一次尝试,参照:http://www.xiaoyunyun.net/index.php/archives/53.html 和 https://blog.csdn.net/wiowei/article/details/121466094在绑定DLL环节失败了第二次尝试:参照:https://zhuanlan.zhihu.com/p/5698198681.修改VS2019,勾选 windows10SDK2.用Visualstudio打开......
  • python3控制结构
    1、介绍控制结构一般为:顺序结构,默认的从前到后执行顺序执行即是条件结构,if结构,python没有switch结构循环结构,while和for结构,以及迭代器,python不存在dowhile结构2、if结构if条件判断:passelif条件判断:passelse:pass3、while结构i=3whilei>0:......
  • ubuntu安装python开发环境
    一般ubuntu是自带python的,不需要安装。这里主要讲,更新pip,设置镜像源,配置虚拟环境,为后续开发做准备。一、更新pippip3configlist如果报没有config命令,说明pip版本不够高。aptinstallpython3-pip这里可以重新安装pip,一般不需要。pip3install-Up......
  • python 正则处理字符串,使用函数
    """在正则截取的字符子串基础上,处理字符串Python的re模块提供了re.sub用于替换字符串中的匹配项。语法:re.sub(pattern,repl,string,count=0,flags=0)参数:pattern:正则中的模式字符串。repl:替换的字符串,也可为一个函数。string:要被查找替换的原始字符串。cou......
  • python3 静态方法,类方法和普通方法
    classMyClass:@staticmethoddefstatic_method():print('静态方法')@classmethoddefclass_method(cls):print('类方法')#普通方法defnormal_method(self):print('普通方法')MyClass.stati......
  • python3 多继承时,父类有相同一个函数的选择
    classPeople:name=''age=0__weight=0def__init__(self,name,age,weight):print("People初始化")self.age=ageself.name=nameself.__weight=weightprint("People......
  • python3 各种方式连接mysql数据库
    print("python连接mysql数据库")#importmysql.connector"""#1使用mysql-connector连接mysqlimportmysql.connectormydb=mysql.connector.connect(host="localhost",user="clever",passwd="1881301"......
  • 列举说明Python同Java及C++的不同之处
    首先是C++C++是在C语言的基础上发展起来的,他包含了C语言的所有内容。同时,也引入了面向对象的概念。优点:1、他包含了C语言的内容,包括指针,使得C++在执行效率上特别的高效。2、引入面向对象的概念,使得开发效率提高。3、提供了很多的库,具有较好的封装性和移植性(代码)。缺点:1、C++比较难......