(表格标题)和
|
(表格数据单元格))一起使用。
每个 HTML 元素可以具有各种属性,这些属性可提供附加信息或修改其行为。网页抓取中最常用的一些属性是
class
、
id
和
href
。和通常
class
都
id
用于定位和获取感兴趣的信息。
href
用于浏览不同的页面。
class ="highlighted important" >
本段落class属性有两个类:“highlighted”和“important”。 p>
<div id = "main-content" > 此div具有唯一ID:“main-content” 。div>
<a href= "https://www.baidu.com"> 访问百度 a>
网络数据抓取主要有三种方式:
-
静态抓取
:这种方式仅解析 HTML,忽略 JavaScript。它不需要浏览器即可从服务器提取网页,获取的内容就是页面源代码中看到的静态部分。通过提供的 URL,您可以直接获取 HTML 结构进行剪切和解析。这也是它被称为“静态抓取”的原因——只需获取并处理服务器返回的静态页面内容。
-
API 抓取
:如今很多网站的架构是 API + JS 的组合。通过分析页面结构,可以找到 API 地址和请求方法,直接向服务器发送请求,获取结构化的 JSON 数据。这种方式最为简便,因为返回的数据是格式化的json 或xml 数据。
-
动态抓取
:这种方式使用浏览器,可以读取通过 JavaScript 生成或修改的内容。简而言之,动态抓取模拟真实用户操作——像用户一样发送输入、改变页面或点击按钮。有时,还需要自动化浏览器操作来获取特定内容。对于此类任务,通常需要使用 Selenium WebDriver 来模拟用户行为。
这三种方式各有优劣,选择哪种方式取决于目标网站的技术架构和防爬策略。
使用 BeautifulSoup 进行静态网页抓取
Beautifulsoup
是一个使用 HTML/XML 解析器并将网页/html/xml 转换为标签、元素、属性和值的树的 Python 库。
安装BeautifulSoup
向想要抓取的网页的 URL 发送一个 HTTP GET 请求,服务器将返回包含 HTML 内容的响应,使用 Python 的
requests
库来请求;使用BeautifulSoup加载解析html。
from bs4 import BeautifulSoup import requests url='https: html_content = requests.get(url).text soup = BeautifulSoup
(html_content, "html") print(soup.prettify())
可以通过
.find([element_tag])
方法轻松从 HTML 结构中提取出我们感兴趣的内容——用于查找单个元素;如果有多个元素,可以使用
.findAll([element_tag])
方法。
table_ele=soup.find('table') tres=table_ele.findAll('tr') for tr in tres: tdes=tr.findAll('td') if len(tdes)>1: print(tdes[0].text,':',tdes[1].text)
使用 Selenium 进行动态网页抓取
Selenium 用于自动化网页应用程序操作。它允许您像人类用户一样打开浏览器并执行任务,例如点击按钮和在网站上搜索特定信息。
安装Selenium和驱动,需要一个驱动程序来与浏览器进行交互。
-
安装 Selenium
:在命令提示符或终端中运行以下命令:
pip install selenium
-
下载驱动程序
:需要浏览器的驱动程序,让 Selenium 能够与浏览器交互。建议使用chrome,检查您的 Google Chrome 版本,然后在
https://developer.chrome.com/docs/chromedriver/downloads?hl=zh-cn
下载对应的 Chromedriver。
下面是一个简单的示例:
import subprocess import threading from selenium import webdriver from selenium.webdriver.chrome.options import Options from selenium.webdriver.common.by import By import time
def openChrome(): cmd = '"C:\Program Files\Google\Chrome\Application\chrome.exe" ' \ '--remote-debugging-port=9222 ' \ '--user-data-dir="d:\selenium\ChromeProfile" ' \ ' --disable-popup-blocking --disable-gpu --safebrowsing-disable-download-protection ' sub_chrome_process = subprocess.Popen(cmd, shell=True)
thread = threading.Thread(target=openChrome) thread.start() time.sleep(2) print(f"{openChrome =}")
def getDriver(): chrome_options = Options() chrome_options.add_argument('--ignore-certificate-errors') chrome_options.add_experimental_option("debuggerAddress", "127.0.0.1:9222") driver = webdriver.Chrome(options=chrome_options) """params = { "behavior": "allow", "downloadPath": download_dir # 设置新的下载路径 } driver.execute_cdp_cmd("Page.setDownloadBehavior", params) driver.execute_cdp_cmd("Security.setIgnoreCertificateErrors", {"ignore": True})""" return driver
driver =getDriver() driver.get("https://bot.sannysoft.com/")
print("*"*50) table_ele=driver.find_element(By.TAG_NAME,"table") for tr_ele in table_ele.find_elements(By.TAG_NAME,"tr"): tdes_ele=tr_ele.find_elements(By.TAG_NAME,'td') if len(tdes_ele)>1: print(tdes_ele[0].text.replace('\n',''),":",tdes_ele[1].text) print("*"*50)
scroll_step = 200 pause_time = 0.3 current_height = driver.execute_script("return document.body.scrollHeight")
for j in range(0, current_height, scroll_step): driver.execute_script(f"window.scrollBy(0, {scroll_step});") time.sleep(pause_time)

这段代码的逻辑和步骤如下:
-
导入必要的库
:
定义 openChrome 函数:
创建并启动线程:
定义 getDriver 函数:
-
创建一个 Options 对象,配置 Chrome 的启动选项。
-
添加忽略证书错误的选项:chrome_options.add_argument('--ignore-certificate-errors')。
-
设置调试地址,使 Selenium 能够连接到已启动的 Chrome 实例:chrome_options.add_experimental_option("debuggerAddress", "127.0.0.1:9222")。
-
使用配置的选项创建 Chrome WebDriver 实例并返回。
获取 WebDriver:
打印表格数据:
-
使用 find_element 和 find_elements 方法找到网页中的 元素及其子元素 和
。
-
遍历表格的每一行,如果该行中有多个单元格(
|
),则打印第一个和第二个单元格的文本内容。
-
滚动页面:
通过这段代码,您可以实现自动化浏览器操作,抓取网页上的表格数据,并进行页面滚动,以获取更多信息。
特别注意的如果是直接打开的chrome 浏览器的话(driver =webdriver.Chrome()) ,WebDriver 标记为True,有较多的网站防爬取判断,被网站拦截掉,可以直接先开启远程模式打开chrome ,然后创建dirver连接到debuggerAddress 上驱动chrome 。
以下是实践过程中点滴总结:
-
网站数据爬取是全栈的技术活,需要了解HTTP、HTML、Python、Selenium、BeautifulSoup、正则表达式、验证码识别等。
-
从网站进行数据爬取和解析本质上可以理解网页的非格式化数据逆向为格式化数据的过程;不同完整需要不同的方式和策略,特别是网站防爬设置、流量控制,需要控制速率、模拟一些真人操作的一些行为。
-
内容的解析和格式化才是最具挑战性的工作,特别是解析文档类的数据,正则表达式的功底是需要的。
网站数据爬取是一项全栈技术,涉及 HTTP、HTML、Python、Selenium、BeautifulSoup 和正则表达式等工具。成功抓取依赖于对网页结构的理解、绕过防爬机制及流量控制。解析与格式化是其中最具挑战的环节,特别是文档类数据的处理,需要扎实的正则表达式能力。
预览时标签不可点
微信扫一扫
关注该公众号
![]()
微信扫一扫
使用小程序
:
,
。
视频
小程序
赞
,轻点两下取消赞
在看
,轻点两下取消在看
分享
收藏
';
videoPlaceHolderSpan.style.cssText = "width: " + obj.w + "px !important;";
insertAfter(videoPlaceHolderSpan, a);
var mid = "2247490121" || "" || "";
var biz = "Mzg2NzgzMjU5MA==" || "";
var sessionid = "" || "svr_34e0146f6fc";
var idx = "1" || "";
var hitInfos = [
];
(function setHitStyle(parentNode, copyIframe, index, vid) {
var ret = (hitInfos || []).find(function (info) { return info.video_id === vid; } );
if (!ret) return;
var ori = ret.ori_status;
var hit_biz_headimg = ret.hit_biz_headimg + '/64';
var hit_nickname = ret.hit_nickname;
var hit_username = ret.hit_username;
var sourceBiz = ret.hit_bizuin;
var selfUserName = "gh_dba8fcd77b28";
if (ori === 2 && selfUserName !== hit_username) {
var videoBar = document.createElement('div');
var videoBarHtml = '';
videoBarHtml += ' 以下视频来源于 ';
videoBarHtml += ' ';
videoBarHtml += ' ';
videoBarHtml += ' ' + hit_nickname + ' ';
videoBarHtml += ' ';
videoBarHtml += ' ';
videoBarHtml += ' ';
videoBarHtml += ' ';
videoBar.innerHTML = videoBarHtml;
var spanContainer = document.getElementById('js_mp_video_container_' + index);
if (spanContainer) {
spanContainer.parentNode.insertBefore(videoBar, spanContainer);
} else if (parentNode.contains && parentNode.contains(copyIframe)) {
parentNode.insertBefore(videoBar, copyIframe);
} else {
parentNode.insertBefore(videoBar, parentNode.firstElementChild);
}
var avatorEle = document.getElementById(hit_biz_headimg + index);
var avatorSrc = avatorEle.dataset.src;
console.log('avatorSrc' + avatorSrc);
if (ret.hit_biz_headimg) {
avatorEle.style.backgroundImage = 'url(' + avatorSrc + ')';
}
}
})(a.parentNode, a, i, vid);
a.style.cssText += ";width: " + obj.w + "px !important;";
a.setAttribute("width", obj.w);
if (window.__zoom != 1) {
a.style.display = "block";
videoPlaceHolderSpan.style.display = "none";
a.setAttribute("_ratio", obj.ratio);
a.setAttribute("_vid", vid);
} else {
videoPlaceHolderSpan.style.cssText += "height: " + (obj.h - obj.sdh) + "px !important;margin-bottom: " + obj.sdh + "px !important;";
a.style.cssText += "height: " + obj.h + "px !important;";
a.setAttribute("height", obj.h);
}
a.setAttribute("data-vh", obj.vh);
a.setAttribute("data-vw", obj.vw);
if (a.getAttribute("data-mpvid")) {
a.setAttribute("data-src", location.protocol + "//mp.weixin.qq.com/mp/readtemplate?t=pages/video_player_tmpl&auto=0&vid=" + vid);
} else {
a.setAttribute("data-src", location.protocol + "//v.qq.com/iframe/player.html?vid=" + vid + "&width=" + obj.vw + "&height=" + obj.vh + "&auto=0");
}
}
})();
(function () {
if (window.__zoom != 1) {
if (!window.__second_open__) {
document.getElementById('page-content').style.zoom = window.__zoom;
var a = document.getElementById('activity-name');
var b = document.getElementById('meta_content');
if (!!a) {
a.style.zoom = 1 / window.__zoom;
}
if (!!b) {
b.style.zoom = 1 / window.__zoom;
}
}
var images = document.getElementsByTagName('img');
for (var i = 0, il = images.length; i < il; i++) {
if (window.__second_open__ && images[i].getAttribute('__sec_open_place_holder__')) {
continue;
}
images[i].style.zoom = 1 / window.__zoom;
}
var iframe = document.getElementsByTagName('iframe');
for (var i = 0, il = iframe.length; i < il; i++) {
if (window.__second_open__ && iframe[i].getAttribute('__sec_open_place_holder__')) {
continue;
}
var a = iframe[i];
a.style.zoom = 1 / window.__zoom;
var src_ = a.getAttribute('data-src') || "";
if (!/^http(s)*\:\/\/v\.qq\.com\/iframe\/(preview|player)\.html\?/.test(src_)
&& !/^http(s)*\:\/\/mp\.weixin\.qq\.com\/mp\/readtemplate\?t=pages\/video_player_tmpl/.test(src_)
) {
continue;
}
var ratio = a.getAttribute("_ratio");
var vid = a.getAttribute("_vid");
a.removeAttribute("_ratio");
a.removeAttribute("_vid");
var vw = a.offsetWidth - (getOuterW(a) || 0);
var vh = vw / ratio;
var h = vh + (getOuterH(a) || 0)
a.style.cssText += "height: " + h + "px !important;"
a.setAttribute("height", h);
if (/^http(s)*\:\/\/v\.qq\.com\/iframe\/(preview|player)\.html\?/.test(src_)) {
a.setAttribute("data-src", location.protocol + "//v.qq.com/iframe/player.html?vid=" + vid + "&width=" + vw + "&height=" + vh + "&auto=0");
}
a.style.display = "none";
var parent = a.parentNode;
if (!parent) {
continue;
}
for (var j = 0, jl = parent.children.length; j < jl; j++) {
var child = parent.children[j];
if (child.className.indexOf("js_img_placeholder") >= 0 && child.getAttribute("data-vid") == vid) {
child.style.cssText += "height: " + h + "px !important;";
child.style.display = "";
}
}
}
}
})();
})();
var anchor_tree_msg = '';
|
|