爬虫学习 | 03 爬虫静态网页的爬取(1)
学习的资料是:python chatgpt 网络爬虫从入门到精通
目录
Step1:基本的环境
Step2:ai辅助解决问题实现代码功能:
Step3:网页的初步分析:
Step4:静态网页的爬取
爬取信息:
实操:
Step1:基本的环境
单独创建一个爬虫的虚拟环境,隔离开其他的工作
如果不能这样做可以直接下载python 3.11的版本即可
输入y即可:
创建完成:
Vscode里面选择刚才创建的环境:
检查一下都有什么库:
下载爬虫所需要的:
pip install requests selenium beautifulsoup4 pandas
如果下载的很慢记得用镜像
pip install requests selenium beautifulsoup4 pandas -i https://pypi.tuna.tsinghua.edu.cn/simple
测试一下python的编程环境:
接下来就是python的一些基本操作,没有学过的可以看看书,我们跳到ai辅助编程,看看书本是怎么系统讲解的:
Step2:ai辅助解决问题实现代码功能:
好的我看了,这个书不如自己的好用,他竟然用文心一下辅助编程,,,其实我们可以下载一些可以嵌入vs code的小工具,比如通义灵码。
书中还介绍了如何写提示词prompt,建议B站去看一下速成,会更有趣易懂����
Step3:网页的初步分析:
- 查看源码:crtl+u
Ctrl+F在页面打开搜索框,方便快速定位自己想要了解的内容
开发者工具
<F12> 或者 ctrl+shift+i
可以更改试图:
右键,检查,开发者工具中会快速跳转到对应位置:
判断网页类型:
加载内容判断:不断加载新的内容,网址始终不变,右侧滚动条越来越短(这是动态页面)
网页源码判断:
右键查看源码:网站服务器返回给浏览器的原始源代码
开发者工具查看源码:开发者工具看到的是浏览器对原始的源代码做了错误的修正和动态加载的结果。(ps:会尝试自动修复一些常见的错误,比如缺失的闭合标签等。)
两者基本相同则静态
举个例子:
汽车之家:我是觉得没有什么区别的,而且他的右边的滚动条是一直不变的,但是它是动态网址。
所以我找了一个新的思路:
静态网站的网址可以是任何以.html、.htm、.shtml等为后缀的网址,这些网址通常指向的是服务器上的静态HTML文件。
根据这个我来找一个静态的网页:
Chinadaily里的一篇文章:这一定是静态页面咯!
Step4:静态网页的爬取
其实这个是好操作的,有一个web scrapy的插件能无代码爬取,但是有一些他是不能爬到的,说到这个,当是我以为会这个插件就是学会爬虫了,开心的去面试,then面试官让我爬取一个网址的信息,结果面试官说我爬出来的信息是残缺的,哈哈哈~
爬取信息:
获取包含所需数据的源代码;
从源代码中提取数据;
对数据进行清洗和存储。
实操:
- 确定目标页面类型:静态页面
- 网址:Changing his tune for a dream - Chinadaily.com.cn
- 获取浏览器的User-Agent:
(1)键入:chrome://version
(2)找到“用户代理”,将其对应的字符串copy下来
Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.0.0 Safari/537.36
确定目标网页的编码格式:
找到head,找到第一个meta,目标网页编码格式:utf-8
编写代码:
(1)获取包含所需数据的源代码;
import requests
url = 'https://www.chinadaily.com.cn/a/202409/21/WS66ee2395a3103711928a903c.html'
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.0.0 Safari/537.36"
}
response = requests.get(url=url, headers=headers)
response.encoding = 'utf-8'
result = response.text
with open(file='html_code.txt', mode='w', encoding='utf-8') as file:
file.write(result)
(2)从源代码中提取数据;
如果包含数据的网页源代码有一定的规律,那么可以使用正则表达式对字符串进行匹配,从而提取所需要的数据。
正则表达式由一些特定字符组成-普通字符和元字符。
Python内置处理正则表达式的re模块,在爬虫任务中主要使用的是模块的findall()函数。
Test.ipynb (2)
Findall()返回值是一个列表,即使只提取一个子字符串,返回的依旧是一个列表。如果没有任何结果,则返回一个空列表。
爬虫常用的是两种非贪婪匹配法:
(.*?) 和 .*?
(.*?):提取A和B之间的文本
.*?:代替A和B之间的文本,不提取
分析网页源代码并编写正则表达式:
<div class="tw4">
<div class="tw4_p"><a target="_blank" shape="rect" href="//www.chinadaily.com.cn/a/202409/17/WS66e8d490a3103711928a83ba.html"><img width="140" height="90" src="//img2.chinadaily.com.cn/images/202409/17/66e8e376a3103711c348696e.jpeg" /></a></div>
<div class="tw4_t"><a target="_blank" shape="rect" href="//www.chinadaily.com.cn/a/202409/17/WS66e8d490a3103711928a83ba.html">Festive China: Mid-Autumn Festival</a></div>
</div>
编写的正则表达式:
<div class="tw4_t"><a target="_blank" shape="rect" href=".*?">(.*?)</a></div>
代码:
import re
with open(file='html_code.txt', mode='r', encoding='utf-8') as f:
result = f.read()
p_title = r'<div class="tw4_t"><a target="_blank" shape="rect" href=".*?">(.*?)</a></div>'
title = re.findall(p_title, result, re.S)
print(len(title))
print(title)
// 整合:
import requests
import re
url = 'https://www.chinadaily.com.cn/a/202409/21/WS66ee2395a3103711928a903c.html'
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.0.0 Safari/537.36"
}
response = requests.get(url=url, headers=headers)
response.encoding = 'utf-8'
result = response.text
p_title = r'<div class="tw4_t"><a target="_blank" shape="rect" href=".*?">(.*?)</a></div>'
title = re.findall(p_title, result, re.S)
print(len(title))
print(title)
编写css选择器:
.tw4_t a
然后ctrl+F进行搜索,有四条符合规则,是对的
使用beautifulsoup进行数据的提取
代码:
import requests
from bs4 import BeautifulSoup
url = 'https://www.chinadaily.com.cn/a/202409/21/WS66ee2395a3103711928a903c.html'
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.0.0 Safari/537.36"
}
response = requests.get(url=url, headers=headers)
response.encoding = 'gbk'
result = response.text
# css选择器
soup = BeautifulSoup(result, 'lxml')
title_tags = soup.select('.tw4_t a')
print(len(title_tags))
print(title_tags)
for title_tag in title_tags:
print(title_tag.get_text())