03 爬虫案例之爬取百度贴吧

介绍

本案例只是为了巩固Xpath语法的使用,不会涉及太深的爬虫的知识

分析:

一般我们爬取某个网站页面,有以下几点步骤:

1、获取爬取目标的地址

2、明确需求,也就是要知道获取网页中的哪些数据

3、明确目标后,通过相应的解析语法(Xpath)去解析网页的结构,从而获取想要的数据

4、编写代码实现

1、获取爬取目标的地址

以百度贴吧为例:

程序员吧-百度贴吧--程序员之家,全球最大的程序员中文交流区。--程序员(英文Programmer)是从事程序开发、维护的专业人员。一般将程序员分为程序设计人员和程序编码人员,但两者的界限并不非常清楚,特

2、明确需求

获取贴吧的每条帖子的标题,如下图:

3、使用Xpath解析网页的结构获取想要的数据

1、通过浏览器工具快速定位到要获取的数据的标签在网页中的位置

1、右键网页,点击检查

 2、然后弹出

3、点击左上角的箭头标志

 4、将鼠标悬停在网页的数据上,左边的显示就会自动跳转到相应的标签,既然是获取帖子的标题,那么我们就鼠标悬停在一个帖子的标题上

定位是定位到了,但是这是我们想要的吗,明显不是,因为这只是定位到一条帖子而已,明显不符合我们的需求,我们是想要获取整个网页(注意这里是网页,不是网站)的所有帖子的标题 。

其实定位到一条已经完成一半了,因为其他帖子的标签结构和属性都是同样的,不会有啥区别,做过前端的兄弟都知道。那么问题来了,既然都一样,为什么不直接使用,这就又要说一个前端的知识,其实大多数网站的布局就像是由许多拼图构成,那么帖子这部分内容就在一块拼图中,我们现在就是要找到这块拼图,从Xpath 的语法上看,我们是通过路径查找和属性值定位来定位标签,如果直接用标签属性值定位也行,因为但一下子就这样定位到明显不保险,有可能多出不想要的数据。

思路:

1、先通过路径查找,找到存放所有帖子的父标签

2、既然帖子的标签结构和属性值都一样,随便找到其中的一个帖子解析就行,后面会写例子看下效果

2.使用Xpath-helper插件验证Xapth语法是否正确获取数据

知道了数据的位置,我们就开始写Xpath语法来定位数据,那么我们如何知道我们写的语法对不对,这使用我们的Xpath-helper插件来验证。

1、首先我们先观察一下,贴吧中一个网页有多少条帖子

        不包含广告,一共50条,因此,只要我们写的语法能获取50条帖子的数据就是正确的

2、使用插件,点击右上角的拼图

3、点击Xpath-helper插件

 4、弹出两个框

 5、左边的框是输入我们的Xapth语法的,右边是根据语法自动获取到的数据

编写Xpath语法

1、只使用属性值定位(不推荐)

通过鼠标定位其中的一条帖子

<a rel="noreferrer" href="/p/7598616748" title="提供日千万预算,长期高价收wap量,正规无感广告,寻站长合作共" target="_blank"
class="j_th_tit xh-highlight">提供日千万预算,长期高价收wap量,正规无感广告,寻站长合作共
</a>

语法:

//a[@class="j_th_tit"]

效果:

可以获取五十条数据,语法正确,那么为啥不推荐,举个例子,我们不用class这个属性,用rel这个属性

//a[@rel="noreferrer"]

 效果:

230条数据,明显错误。 



2、结合路径查找和属性查找(推荐)

首先要知道帖子这块拼图的标签,只需能包括帖子这部分的内容的标签即可

 从图中可以知道帖子的信息是在li标签中的,,而我们的想要的数据必然在li标签中,解析li标签

 我们可以根据a标签一级一级往上找,有一个问题,就是会出现同样的标签,并且两个同级,那么如何区分,如下图:

可以看出,我们想要的内容在第二个div标签下,如何区分两者,很简单通过属性值区分即可

语法:

//ul[@id="thread_list"]/li/div/div[@class="col2_right j_threadlist_li_right "]/div/div/a

效果:

语法的书写是根据自己而定的,所以只要能获取到正确的数据即可

3、获取数据

我们上面所作的只是定位到数据所在的标签,并没有真正获得值,根据数据在标签中的形式获取

<a rel="noreferrer" href="/p/7598616748" title="提供日千万预算,长期高价收wap量,正规无感广告,寻站长合作共" target="_blank"
class="j_th_tit xh-highlight">提供日千万预算,长期高价收wap量,正规无感广告,寻站长合作共
</a>

可以看到在a标签的title属性的值就是我们想要的数据,在<a></a>之间也存在我们想要的值,因此有两种写法,根据自己喜好

语法:

写法一:

//ul[@id="thread_list"]/li/div/div[@class="col2_right j_threadlist_li_right "]/div/div/a/text()

效果:

 

 写法二:

//ul[@id="thread_list"]/li/div/div[@class="col2_right j_threadlist_li_right "]/div/div/a/@title

 效果:

4、编写代码实现

代码:

import requests
import time
from lxml import etree




def getHTMLContent(url):

    # 伪装用户代理,防反爬
    header = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.77 Safari/537.36'
    }

    # 向url发送get请求
    respone = requests.get(url,headers = header)

    # 将返回的二进制流文件转化成文本文件
    content = respone.text

    # 减少一些无用的标签的干扰,这个标签在html语言是属于注释标签
    content = content.replace('<!--', '')
    content = content.replace('-->', '')

    # 将返回的html文本文件转化成xpath能解析的对象
    tree = etree.HTML(content)

    # 根据xpath语法获取内容
    titles = tree.xpath('//ul[@id="thread_list"]/li/div/div[@class="col2_right j_threadlist_li_right "]/div/div/a/text()')

    # 循环打印结果
    for title in titles:
        print(title)





if __name__ =="__main__":

    url = "https://tieba.baidu.com/f?kw=%E7%A8%8B%E5%BA%8F%E5%91%98&ie=utf-8&pn=50"
    getHTMLContent(url)

结果:

猜你喜欢

转载自blog.csdn.net/m0_55868614/article/details/121161401