网络爬虫--Python

网络爬虫–Python,以百度关键词搜索为例

selenium方法

背景:使用requests向百度发起请求容易引起“百度安全验证”问题

Selenium是一个用于自动化浏览器操作的工具,常用于测试网页应用程序和执行Web任务, 它提供了多种编程语言的客户端库,如Python、Java、C#等,用于控制浏览器的行为 。通过编写代码,实例化一个浏览器,可以模拟用户在浏览器中的操作,比如点击链接、填写表单、提交数据等

缺点:运行速度较慢

安装环境

1.下载python的Selenium

pip install Selenium -i https://pypi.tuna.tsinghua.edu.cn/simple

2.下载beautifulsoup4用于解析请求结果

pip3  install  beautifulsoup4  -i https://pypi.tuna.tsinghua.edu.cn/simple

下载浏览器驱动

下载对应的浏览器驱动(Browse Driver)以供Selenium调用,以FireFox浏览器为例

从 Mozilla 的 GitHub 下载最新的 geckodriver,Windows下载win32版本。

在这里插入图片描述

Python脚本

导入依赖包
# 注意firefox浏览器是selenium.webdriver.firefox不要选错
from selenium import webdriver
from selenium.webdriver.firefox.service import Service
from selenium.webdriver.firefox.options import Options
from bs4 import BeautifulSoups
driver配置
options = Options()
options.add_argument('-headless')  # 浏览器不弹出
options.binary_location = r'C:\Program Files\Mozilla Firefox\firefox.exe'  # 替换为你的Firefox可执行文件路径
options.set_capability('acceptInsecureCerts', True)


s = Service(executable_path=r'./geckodriver.exe')    # 刚刚下载的firefox驱动路径
driver = webdriver.Firefox(service=s, options=options)
内容提取

确定内容提取的区域,获取CSS路径

百度搜索页面在这里插入图片描述
如上图,我们在进行关键词检索后,页面上不同的区域会有不同的文本,而我们只想要提取页面左半部分中间区域的内容,这时候我们要确定内容提取的区域。

在浏览器页面按下F12 进入开发者模型,在开发者模式下,在查看器下移动鼠标可以查看元素涵盖的区域,不断展开元素滑动鼠标,我们可以确定内容提取的区域所属的元素

浏览器上的HTML查看器在这里插入图片描述
CSS路径复制在这里插入图片描述
在确定好内容区域后,可以选中元素右击复制其CSS路径

百度搜索的URL

百度搜索的url如下所示:

wd = "今天星期几"    # 要搜索的关键词
url = f"https://www.baidu.com/s?wd={wd}"
文本内容提取

首先获取整个页面信息

driver.get(url)
# 获取页面的源代码
page_source = driver.page_source
soup = BeautifulSoup(page_source, 'html.parser')

特定区域内容提取

content = ''
css_path = 'div#wrapper.wrapper_l.wrapper_new div#wrapper_wrapper div#container.sam_newgrid.container_l div#content_left'
elements = soup.select(css_path)
for element in elements:
    content += element.get_text(strip=True)
print("Found the text:", content)
完整程序
from selenium import webdriver
from selenium.webdriver.firefox.service import Service
from selenium.webdriver.firefox.options import Options
from bs4 import BeautifulSoup


options = Options()
options.add_argument('-headless')  # 浏览器实例后台运行
options.binary_location = r'C:\Program Files\Mozilla Firefox\firefox.exe'  # 替换为你的Firefox可执行文件路径
options.set_capability('acceptInsecureCerts', True)

s = Service(executable_path=r'./geckodriver.exe')
driver = webdriver.Firefox(service=s, options=options)


wd = "今天发什么了什么大事"
url = f"https://www.baidu.com/s?wd={wd}"

driver.get(url)
# 获取页面的源代码
page_source = driver.page_source
soup = BeautifulSoup(page_source, 'html.parser')

content = ''
css_path = 'div#wrapper.wrapper_l.wrapper_new div#wrapper_wrapper div#container.sam_newgrid.container_l div#content_left'
elements = soup.select(css_path)
for element in elements:
    content += element.get_text(strip=True)
print("Found the text:", content)

driver.quit()

requests方法

请求头

请求头(Request Headers)是HTTP协议中用于传递关于请求的额外信息的一部分。以下是关于请求头的详细介绍:

  • 请求头包含了客户端(通常是浏览器或应用程序)与服务器之间进行通信所需的元数据,这些元数据通常包括客户端的环境信息、请求偏好或身份验证等,如操作系统、浏览器类型、请求方法(如GET、POST等)、语言、接受的MIME类型、字符编码、内容类型等。

  • 服务器根据这些信息来处理请求并生成适当的响应。

非服务器(个人PC)在没有提供headers信息的情况下,向百度发起关键词检索请求并不会收到正确的响应,或者容易引起百度安全验证问题,尤其是在没有提供Cookie的情况下,见下图。

请求失败在这里插入图片描述
因此,我们要提供一个信息完整的请求头向才能百度发起正确的请求。

我们可以通过浏览器在百度中搜索一下关键词(浏览器向百度发起一次关键词检索请求),然后按F12进入开发者模式,点击网络选中发起的请求,可以在右边区域看到完整的请求信息,点击请求头就可以看到完整的请求头信息,见下图。
在这里插入图片描述

headers信息写成python格式:

headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/93.0.4577.63 Safari/537.36',
        'Cookie': '把你的Cookie放在这里',
        'Accept': 'image/avif,image/webp,image/apng,image/svg+xml,image/*,*/*;q=0.8',
        'Accept-Encoding': 'gzip, deflate, br',
        'Accept-Language': 'zh-CN,zh;q=0.9',
        'Host': 'www.baidu.com'
        }

请求结果

这时候可以看到已经能向百度请求正确的结果了,但是还仍然需要解析才能获取文本信息,完整代码:

import requests

wd = "日期"
url = f"https://www.baidu.com/s?wd={wd}"
headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/93.0.4577.63 Safari/537.36',
        'Cookie': '把你的Cookie放在这里',
        'Accept': 'image/avif,image/webp,image/apng,image/svg+xml,image/*,*/*;q=0.8',
        'Accept-Encoding': 'gzip, deflate, br',
        'Accept-Language': 'zh-CN,zh;q=0.9',
        'Host': 'www.baidu.com'
        }
response = requests.get(url, headers=headers,)
html_content = response.text
print(response.text)

解析

查找目标元素

在百度页面上,通常会存在着各种的信息,如广告,热搜等,这些都不是我们的目标,我们希望能够提取有用的信息。这时候我们应该先查看页面HTML的结构。

在一次百度关键词搜索后在界面按F12进入开发者模式,在查看器可以看到整个页面的构成格式。

浏览器上的HTML查看器在这里插入图片描述

经过查找,我们可以发现,百度关键词搜索的结果都在div元素下,每个结果都有不同的id,且都属于result或者result-op这两个类,其中result-op是百度自家产品提供的结果,这两个类具有相同的子类c-container,见下图。

搜索结果对应的元素在这里插入图片描述
对于搜索结果是广告(和其他搜索结果同层级)的情况,则只有div元素,没有具体的类属。

完整的CSS路径示例:

html body.cos-pc div#wrapper.wrapper_l.wrapper_new div#wrapper_wrapper div#container.sam_newgrid.container_l div#content_left div#1.result-op.c-container.xpath-log.new-pmd

因此,我们可以利用这一特性提取目标元素下的内容信息。

HTML解析

BeautifulSoup的选择器可以使用类选择器和层次选择器,而不必使用特定的id。这样,在我们不知道确切id的情况下,可以选择同样的类的元素。

从上面的分析结果可我们以得出需要提取的类的层级结构,可以构建选择器:

selector = 'div.result.c-container'

内容提取

soup = BeautifulSoup(html_content, 'html.parser') # 构建解析器 
selector = 'div.result.c-container'    
elements = soup.select(selector)    # 元素提取
content = ''
if elements:
    for elements in elements:
        content += elements.get_text(strip=True) + '\n'

print(content)

完整程序

import requests
from bs4 import BeautifulSoup

wd = "今天是几号?"
url = f"https://www.baidu.com/s?wd={wd}"

headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/93.0.4577.63 Safari/537.36',
        'Cookie': '把你的Cookie放在这',
        'Accept': 'image/avif,image/webp,image/apng,image/svg+xml,image/*,*/*;q=0.8',
        'Accept-Encoding': 'gzip, deflate, br',
        'Accept-Language': 'zh-CN,zh;q=0.9',
        'Host': 'www.baidu.com'
        }

response = requests.get(url, headers=headers)

html_content = response.text

soup = BeautifulSoup(html_content, 'html.parser')
selector = 'div.result.c-container'
elements = soup.select(selector)
content = ''
if elements:
    for elements in elements:
        content += elements.get_text(strip=True) + '\n'

print(content)
  • 7
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

丶薛定谔的叮当猫

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值