Python爬虫(3) --爬取网页文本

文章目录

爬虫

Python 爬虫是一种自动化工具,用于从互联网上抓取网页数据并提取有用的信息。Python 因其简洁的语法和丰富的库支持(如 requests、BeautifulSoup、Scrapy 等)而成为实现爬虫的首选语言之一。

Python爬虫获取浏览器中的信息,实际上是模仿浏览器上网的行为。上一篇中,我们尝试着爬取了一个网站的页面,完成获取信息需要完成三步:

  1. 指定url
  2. 发送请求
  3. 获取你想要的数据

那这次我们来试试爬取网页中的文本内容:我们再添加一步

  1. 数据解析

我们试着爬取一个以下网站页面内的电影名、导演、演员、上映时间、国家和剧情类型:

python 复制代码
https://movie.douban.com/top250

我们按步骤一步一步来:

爬取文本

按步骤获取:

指定url

python 复制代码
url = "https://movie.douban.com/top250"

发送请求

python 复制代码
import fake_useragent#伪装身份发送请求
import requests
#UA伪装  让你认为我是一个浏览器
    head = {
        "User-Agent":fake_useragent.UserAgent().random
    }
	response = requests.get(url,headers=head)

获取想要的数据

python 复制代码
	res_text = response.text
	 #print(res_text)

数据解析

xpath语言

在Python中,XPath(XML Path Language)是一种在XML和HTML文档中查找信息的语言。它允许你通过指定元素的路径来定位和选择文档中的节点(如元素、属性等)。Python通过一些库支持XPath的使用,最著名的是lxml和BeautifulSoup(虽然BeautifulSoup本身不直接支持XPath,但可以通过lxml解析器来间接使用XPath)。

所以在使用xpath之前,我们需要先Python安装一个lxml包:

python 复制代码
pip install lxml

安装完成后,导入包:

python 复制代码
from lxml import etree

解析获得的数据内容:

python 复制代码
tree = etree.HTML(res_text) #将HTML文本(通常是网页的源代码)解析

找出我们想要的文本内容,第一步点击元素Elements,接着点击第二步的箭头,点击我们想要得到的内容,右边开发者控制台会出现其所在的位置。

定位目标位置

从开发者控制台中我们能看到多个目录,索引定位,从1开始。

定位所有的li标签:

  1. 逐层定位:

xpath返回的都是列表:我们接受一下它:

python 复制代码
li_list = tree.xpath("/body/div[3]/div[1]/div[1]/div[1]/ol/li")

这样逐层找很麻烦复杂。

  1. 属性定位

找到class属性,按ctrl+ "f"健查询开发者控制台中属性出现的个数。如果只有一个,可以直接越级定位。

python 复制代码
li_list = tree.xpath("//ol[@class='grid_view']/li")

定位完成后,确定有没有解析到数据。打印li_list:

python 复制代码
print(li_list)		#返回是列表形式
--------------------------
[<Element li at 0x1b1d32e3f88>, <Element li at 0x1b1d32a23c8>, <Element li at 0x1b1d3289c88>, <Element li at 0x1b1d32e8148>, <Element li at 0x1b1d32e82c8>, <Element li at 0x1b1d32e81c8>, <Element li at 0x1b1d32e8208>, <Element li at 0x1b1d32e8248>, <Element li at 0x1b1d32e8188>, <Element li at 0x1b1d32e8288>, <Element li at 0x1b1d32e8348>, <Element li at 0x1b1d32e8f08>, <Element li at 0x1b1d3301208>, <Element li at 0x1b1d3301288>, <Element li at 0x1b1d3301f08>, <Element li at 0x1b1d3301fc8>, <Element li at 0x1b1d331bc88>, <Element li at 0x1b1d331bfc8>, <Element li at 0x1b1d331b488>, <Element li at 0x1b1d331bb88>, <Element li at 0x1b1d331b9c8>, <Element li at 0x1b1d331b748>, <Element li at 0x1b1d331b588>, <Element li at 0x1b1d331b648>, <Element li at 0x1b1d331b788>]
具体位置

接着我们来定位每篇电影的电影名、导演、演员、上映时间、国家和剧情类型的位置。

python 复制代码
    for li in li_list:		#利用join方法将列表转化为字符串。
        film_name = "".join(li.xpath(".//span[@class='title'][1]/text()"))	#text()取标签下的文本
        director_actor_y_country_type = "".join(li.xpath(".//div[@class='bd']/p[1]/text()"))
        print(film_name,director_actor_y_country_type)
-----
肖申克的救赎 
                            导演: 弗兰克·德拉邦特 Frank Darabont   主演: 蒂姆·罗宾斯 Tim Robbins /...
                            1994 / 美国 / 犯罪 剧情
                        
霸王别姬 
                            导演: 陈凯歌 Kaige Chen   主演: 张国荣 Leslie Cheung / 张丰毅 Fengyi Zha...
                            1993 / 中国大陆 中国香港 / 剧情 爱情 同性
                        
........................过多不展示............

正则匹配

拿到内容后,我们发现有大量的空格和文本垃圾,我们要将他们处理干净,将我们的目标内容拿出来。

别忘记导入正则re包哦!

python 复制代码
import re
python 复制代码
    new_str = director_actor_y_country_type.strip()  #strip()去空格
    y = re.match(r"([\s\S]+?)(\d+)(.*?)", new_str).group(2)		#正则匹配,group(2)取出第二组
    country = new_str.rsplit("/")[-2].strip()	#rsplit("/")[-2]以"/"为分隔符分割文本,切片出倒数第二个
    types = new_str.rsplit("/")[-1].strip()
    director = re.match(r"导演: ([a-zA-Z\u4e00-\u9fa5·]+)(.*?)", new_str).group(1)

    try:	#由于有的主演不符合标准,做个正则判断
        actor = re.match(r"(.*?)主演: ([a-zA-Z\u4e00-\u9fa5·]+)(.*?)", new_str).group(2)
    except Exception as e:
        actor = "no"
    #用不常用的符号连接在一起,这样调用的时候只需要以特殊符号分割
    print(film_name + "#" + y + "#" + country + "#" + types + "#" + director + "#" +actor + "\n")
----------------------
挑选两个结果展示:
肖申克的救赎#1994#美国#犯罪 剧情#弗兰克·德拉邦特#蒂姆·罗宾斯
寻梦环游记#2017#美国#喜剧 动画 奇幻 音乐#李·昂克里奇#no		#此电影没有主演,不符合规则,输出"no"

完整爬取展示

完整的爬取过程,将爬取的内容写进文本中:

python 复制代码
import fake_useragent
import requests
from lxml import etree
import re
if __name__ == '__main__':

    #UA伪装  让你认为我是一个浏览器
    head = {
        "User-Agent":fake_useragent.UserAgent().random
    }
    
    # 打开一个文件写入数据
    fp = open("./doubanFilm.txt", "w", encoding="utf8")
    
    # 1、指定url
    url = "https://movie.douban.com/top250"

    # 2、发送请求    返回的数据在response对象内
    response = requests.get(url,headers=head)

    #3、获取想要的数据
    res_text = response.text
    # print(res_text)

    tree = etree.HTML(res_text)
    
    # 定位所有的li标签
    li_list = tree.xpath("//ol[@class='grid_view']/li")
    # print(li_list)
    for li in li_list:
        film_name = "".join(li.xpath(".//span[@class='title'][1]/text()"))
        director_actor_y_country_type = "".join(li.xpath(".//div[@class='bd']/p[1]/text()"))
        # print(film_name,director_actor_y_country_type)

        new_str = director_actor_y_country_type.strip()
        y = re.match(r"([\s\S]+?)(\d+)(.*?)", new_str).group(2)
        country = new_str.rsplit("/")[-2].strip()
        types = new_str.rsplit("/")[-1].strip()
        director = re.match(r"导演: ([a-zA-Z\u4e00-\u9fa5·]+)(.*?)", new_str).group(1)
        try:
            actor = re.match(r"(.*?)主演: ([a-zA-Z\u4e00-\u9fa5·]+)(.*?)", new_str).group(2)
        except Exception as e:
            actor = "no"

        fp.write(
            film_name + "#" + y + "#" + country + "#" + types + "#" + director + "#" +
            actor + "\n")
    fp.close()

总结

本篇介绍了,如何将网页内想获取的文本内容爬虫出来:

  1. 指定url:找到网页地址
  2. 发送请求:requests请求
  3. 获取你想要的数据:文本接收,请求到的内容
  4. 数据解析:
    1. xpath语言:定位到目标位置
    2. re正则匹配:精准取出目标内容,去除杂质
相关推荐
小馒头学python2 分钟前
机器学习是什么?AIGC又是什么?机器学习与AIGC未来科技的双引擎
人工智能·python·机器学习
k09333 分钟前
sourceTree回滚版本到某次提交
开发语言·前端·javascript
神奇夜光杯11 分钟前
Python酷库之旅-第三方库Pandas(202)
开发语言·人工智能·python·excel·pandas·标准库及第三方库·学习与成长
Themberfue14 分钟前
Java多线程详解⑤(全程干货!!!)线程安全问题 || 锁 || synchronized
java·开发语言·线程·多线程·synchronized·
plmm烟酒僧15 分钟前
Windows下QT调用MinGW编译的OpenCV
开发语言·windows·qt·opencv
千天夜23 分钟前
使用UDP协议传输视频流!(分片、缓存)
python·网络协议·udp·视频流
测试界的酸菜鱼27 分钟前
Python 大数据展示屏实例
大数据·开发语言·python
羊小猪~~31 分钟前
神经网络基础--什么是正向传播??什么是方向传播??
人工智能·pytorch·python·深度学习·神经网络·算法·机器学习
晨曦_子画36 分钟前
编程语言之战:AI 之后的 Kotlin 与 Java
android·java·开发语言·人工智能·kotlin
Black_Friend44 分钟前
关于在VS中使用Qt不同版本报错的问题
开发语言·qt