在正式进入网页爬取之前需要首先简单了解一下网页结构:
1.了解网页结构
这个界面是我们平时浏览网页所能看到的界面。
而这个界面才是计算机所看到的界面,该界面包含了由html语言编写的网页代码。(使用F12或右键“检查”进入该界面) 爬取的便是这个界面的内容。
一个完整的HTML网页包含三个标签:<HTML>、<head>、<body>
因此,我们爬取的内容大概率在<body>标签中。
2.抓取某个特定网页的文本内容(初级)
核心逻辑:定位+抓取
2.1 定位
直接进入开发者界面F12,从<body>标签开始,对照着网页界面检查每一个标签容器。发现,我们想要的新闻内容隐藏在<div id="content">标签容器下。定位成功!!!
2.2 抓取
抓取的核心逻辑就是模拟人访问网页并从网页中获取数据,不过这个过程因为有了python代码而变得快速和自动化。那么既然是模拟人访问,那我们首先要使用代码进入网页并对网页的html编码进行解析转存。举个不恰当的例子,你是老板,python是你的好员工,你派遣他去html那里拿点东西。作为一个合格的"theft"(bushi)作为一个合格的员工,执行任务肯定得带点家伙什。这个家伙什就是两个工具包requests和beautifulsoup。
requests工具包主要用于发送http请求并处理http响应(简单点,模拟人打开浏览器网页)。
beautifulsoup工具包用于解析html文档,并转译成python能处理的格式,方便之后的查找。
使用python安装命令pip install安装这两个工具包:-pip install requests
-pip install beautifulsoup4
(安装太慢就把这个加上)-i https://pypi.tuna.tsinghua.edu.cn/simple/
除此之外还需要有身份认证(爱的号码牌),防止反爬检测。 我的号码牌在哪里?在开发者界面-Network选项-随便点一个Headers-找到User agent复制即可。
正式爬取开始,代码及注释如下:
#requests工具包用于发送HTTP请求并处理HTTP响应
import requests
#BeautifulSoup工具包用于用于解析HTML文档,并解析成python能看懂的形式,方便之后的查找输出。
from bs4 import BeautifulSoup
#输入想要抓取的网页链接
url = "https://www.chinadaily.com.cn/a/202310/26/WS653a5916a31090682a5eaf3c.html"
#身份认证,伪装浏览器访问,防止检测(爱的号码牌)
headers = {
"User-Agent": "你自己的号码牌"}
# 发起HTTP请求并获取页面内容,使用headers参数传递请求头信息。
response = requests.get(url, headers=headers)
# 检查是否成功获取页面
if response.status_code == 200:
#将获取到的网页内容以utf-8编码的形式解码保存到一个新的变量html中。
html = response.content.decode("utf-8")
#将HTML文档解析成易于处理的Python对象,保存到变量soup里
soup = BeautifulSoup(html, "html.parser")
#从保存的soup变量里查找标签为 <div> 且属性为 id 属性,属性的值是 "Content"的文本内容。
content = soup.find("div", id="Content").text
print(content)
else:
print("无法访问页面")
爬取成功结果如下:
3.抓取多个网页的文本内容(进阶)
上面是输入一个网页链接,抓取这个网页的内容。反过来想想,既然能抓取到某个页面上的任何内容,那是不是同样能抓取到某个网页上所有的链接,然后逐一提取各个页面上的内容。这个逻辑想通了,问题就能解决了,之前是我输入一个网址去抓取该网址的内容,现在是我直接抓取多个网址,然后批量抓取所有网址的内容。
3.1定位网页链接位置(以China Daily的technology板块为例)
小东西居然藏在这里!!
好!既然找到位置了,我们来看代码,代码分成三部分看。
3.1 抓取多个网页链接中的内容(以China Daily的technology板块为例)
第一部分:老样子,拿着爱的号码牌和家伙什定位到了链接所在的区域<div class="mb10_tw3_01_2"。
第二部分:是精确到我们所在的链接,去除噪音内容,因为我们想要的只是这个标签里的链接,但是第一部分查找是把标签里所有的内容都copy下来了,因此需要清洗一下数据。于是我们从之前保存的内容里面再精确查找,找到标签为a,属性为herf的内容。这样我们就提取到了精确的网址,但现在的网址格式不对(你看上图,网址是不是怪怪的),无法被搜索,因此还需要转换一下,这里就用到了一个新的工具urllib里的urljoin函数,来实现转换。转换之后的absolute_link就是我们抓取的所有网址,她们被统一储存在links列表中,方便我们第三步使用。
第三部分:只看for循环里的结构,是不是很熟悉?只不过加了一个遍历循环,不断的从我们第二部分保存的链接列表里面读取链接然后抓取该链接的内容,直到列表里的链接都循环完毕。最后将爬取到的内容保存在txt文档里(很常规的结构,不必解释)。
#-----------------------------------Part1------------------------------------------------
import requests
from bs4 import BeautifulSoup
from urllib.parse import urljoin
# 定义请求头信息
headers = {
"User-Agent": ""}
# 获取链接的部分,与第一个代码段相同
url = "https://www.chinadaily.com.cn/business/tech"
response = requests.get(url, headers=headers)
if response.status_code == 200:
html = response.content.decode("utf-8")
soup = BeautifulSoup(html, "html.parser")
# 查找包含链接的<div>标签,限定class="mb10 tw3_01_2"
div_elements = soup.find_all("div", class_="mb10 tw3_01_2")
#-----------------------------------Part2------------------------------------------------
# 创建一个空列表来存储链接
links = []
# 提取并保存<a>标签下的href链接到列表
for div_element in div_elements:
link = div_element.find("a", href=True)
if link:
absolute_link = urljoin(url, link["href"])
links.append(absolute_link)
print(absolute_link)
else:
print("无法访问页面")
#-----------------------------------Part3------------------------------------------------
# 创建一个txt文件以写入内容
with open("content.txt", "w", encoding="utf-8") as file:
# 遍历链接并提取内容的部分
for link in links:
response = requests.get(link, headers=headers)
# 检查是否成功获取页面
if response.status_code == 200:
html = response.content.decode("utf-8")
soup = BeautifulSoup(html, "html.parser")
content_div = soup.find("div", id="Content")
if content_div:
content = content_div.text
# 将内容写入txt文件
file.write(content)
file.write("\n\n") # 在不同链接的内容之间添加空行
else:
print(f"在链接 {link} 中找不到内容")
else:
print(f"无法访问链接 {link}")
print("内容已保存到content.txt文件")
成功结果如下!
完结,撒花!