set_time_limit(0);
$url = 'xxxxxxxxxxxx';
$file = 'index.html';
$robot = new Spider(array(
'site' => $url,
'queue' => array( $file),
));
$robot->begin();
class Spider
{
protected $site = '';
protected $extension = array( 'gif', 'jpg', 'png', 'eot', 'svg', 'ttf', 'woff', 'woff2', 'js');
public function __construct( $config = array())
{
$this->site = $config['site'];
Queue::push( $config['queue']);
}
public function begin()
{
while( $file = Queue::pull()) {
$url = $this->comple( $file);
$content = File::save( $file, $url);
if( empty( $content) || !$this->is_match( $url)) continue;
$content = new Content( $content);
$links = $content->links();
foreach ( $links as $k => $link) {
$links[$k] = $this->relative( $url, $link);
}
Queue::push( $links);
log_message('debug', 'contents', array(
'url' => $url,
'links' => $links,
));
}
}
protected function is_match( $url)
{
$info = pathinfo( $url);
if( empty( $info['extension'])) return true;
return !in_array( $info['extension'], $this->extension);
}
protected function relative( $url, $link)
{
$time = null;
$rpos = strrpos($link, '../');
if( $rpos !== false) $time = $time/3;
$time = $time === null ? 0 : $time+1;
$links = trim( $link, './');
$url = explode('/', substr( $url, strlen( $this->site)));
array_pop( $url);
while( $time) {
array_pop( $url);
$time--;
}
$url[] = $links;
return implode( '/', $url);
}
protected function comple( $url)
{
return $this->site.$url;
}
}
class Content
{
protected $content;
public function __construct( $content)
{
$this->content = $content;
}
public function links()
{
$links = array_merge(
$this->href(),
$this->src(),
$this->url(),
);
foreach( $links as $k => $link)
{
$link = trim( $link,'\'"');
$pos = strpos( $link, '?');
if( $pos !== false) $link = substr( $link, 0, $pos);
if( $this->filter( $link)) {
unset( $links[$k]);
continue;
}
$links[$k] = $link;
}
return array_unique($links);
}
protected function href()
{
preg_match_all('/href="(.*?)"/', $this->content,$matches);
return $matches[1];
}
protected function src()
{
preg_match_all('/src="(.*?)"/', $this->content,$matches);
return $matches[1];
}
protected function url()
{
preg_match_all('/url\((.*?)\)/', $this->content,$matches);
return $matches[1];
}
protected function filter( $link)
{
$filters = array(
'#', '+', '%', '//', 'http', 'data:', 'javascript', 'tel', 'mailto', '{{'
);
foreach( $filters as $filter) {
if( substr( $link, 0,strlen( $filter)) == $filter) return true;
}
if( in_array( $link, array( '/', './'))) {
return true;
}
return false;
}
}
class File
{
public static function save( $file, $url)
{
$content = self::read( $url);
self::write( $file, $content);
log_message('debug', 'save file', array(
'url' => $url,
));
return preg_replace("/\s+/", " ", $content);
}
protected static function read( $url)
{
$cache = Cache::get( $url);
$content = $cache ? $cache : Http::request( $url);
$content = $content ? $content : @file_get_contents( $url);
if( !$cache) {
Cache::set( $url, $content);
}
return $content;
}
protected static function write( $file, $content)
{
self::mkdir( $file);
return file_put_contents( $file, $content);
}
protected static function mkdir( $filename)
{
$dir = dirname($filename);
if( is_dir( $dir)) return true;
if( mkdir( $dir, 0777, true)) return true;
}
}
class Queue
{
protected static $data = array();
protected static $worked = array();
public static function pull()
{
$row = array_shift(self::$data);
array_push(self::$worked, $row);
return $row;
}
public static function push( $list)
{
$list = (array)$list;
foreach ($list as $k => $v) {
if( !self::is_worked( $v)) {
array_push(self::$data, $v);
}
}
array_unique( self::$data);
return true;
}
public static function is_worked( $url)
{
return in_array( $url, self::$worked);
}
}
class Cache
{
protected static $dir = './cache/';
public static function set( $name, $value)
{
if( !is_dir( self::$dir)) mkdir( self::$dir);
file_put_contents( self::$dir.md5( $name), $value);
}
public static function get( $name)
{
$file = self::$dir.md5( $name);
if( file_exists( $file)) {
return file_get_contents( $file);
}
return Null;
}
}
class Http
{
public static function request( $url, $params = array(), $method = 'GET', $multi = false, $extheaders = array())
{
if(!function_exists('curl_init')) exit('Need to open the curl extension');
$method = strtoupper($method);
$ci = curl_init();
curl_setopt($ci, CURLOPT_USERAGENT, '');
curl_setopt($ci, CURLOPT_CONNECTTIMEOUT, 3);
$timeout = $multi?30:3;
curl_setopt($ci, CURLOPT_TIMEOUT, $timeout);
curl_setopt($ci, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ci, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ci, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($ci, CURLOPT_HEADER, false);
$headers = (array)$extheaders;
switch ($method) {
case 'POST':
curl_setopt($ci, CURLOPT_POST, TRUE);
if (!empty($params)) {
if($multi) {
if( is_array( $multi)){
foreach($multi as $key => $file) {
$params[$key] = '@' . $file;
}
}
curl_setopt($ci, CURLOPT_POSTFIELDS, $params);
$headers[] = 'Expect: ';
} else {
curl_setopt($ci, CURLOPT_POSTFIELDS, http_build_query($params));
}
}
break;
case 'DELETE':
case 'GET':
$method == 'DELETE' && curl_setopt($ci, CURLOPT_CUSTOMREQUEST, 'DELETE');
if (!empty($params)) {
$url = $url . (strpos($url, '?') ? '&' : '?')
. (is_array($params) ? http_build_query($params) : $params);
}
break;
}
curl_setopt($ci, CURLINFO_HEADER_OUT, TRUE);
curl_setopt($ci, CURLOPT_URL, $url);
if($headers) {
curl_setopt($ci, CURLOPT_HTTPHEADER, $headers);
}
$response = curl_exec($ci);
curl_close ($ci);
return $response;
}
}
function log_message( $level, $message, $context = array())
{
$message = date('Y-m-d H:i:s').' - '. $message;
if( $context) {
$message .= ' - [context] '.json_encode( $context);
}
$message .= "\n";
echo $message;
file_put_contents('./log.log', $message, FILE_APPEND);
}
相关推荐
简单的携程抓取脚本
我这里把很多东西写死了。就放一些逻辑在里边。 完整代码如下 其中用到了模拟浏览器请求。原因是因为requests抓取和模拟浏览器抓取下来的内容不一致。你会很纠结。感兴趣的可以试试。 # -*- encoding: utf-8 -*- # 导包 import gevent # 猴子补丁 from gevent import monkey monkey.patch_all() import re...
实用Python爬虫脚本分享:轻松抓取网页数据!
在日常工作和学习中,数据采集是一项常见的需求。手动复制网页数据既费时又容易出错,而通过 Python 爬虫技术可以快速、高效地抓取所需内容。完整代码和详细使用教程已上传至 优快云 资源模块,大家可以免费下载!
直流有刷电机三环PID控制:从硬件配置到软件调试全解析
本文全面解析了直流有刷电机的三环PID控制技术,涵盖从硬件选型(如驱动板、编码器)到STM32软件配置的全过程。详细阐述了位置环、速度环、电流环的串级协同工作原理与调试方法,并提供了位置式PID算法的C语言实现代码及参数整定技巧,旨在帮助开发者实现精准、稳定的电机运动控制。
10个Python脚本来自动化你的日常任务
在这个自动化时代,我们有很多重复无聊的工作要做。我们学习Python必然是为了找到高薪的工作,下面这些面试题是来自阿里、腾讯、字节等一线互联网大厂最新的面试资料,并且有阿里大佬给出了权威的解答,刷完这一套面试资料相信大家都能找到满意的工作。Python所有方向的技术点做的整理,形成各个领域的知识点汇总,它的用处就在于,你可以按照上面的知识点去找对应的学习资源,保证自己学得较为全面。厌倦了手动将您的 PDF 书籍转换为有声读物,那么这是你的自动化脚本,它使用 GTTS 模块将你的 PDF 文本转换为音频。
Windows下的Geant4安装教程
本教程将从0开始展示在Windows下如何安装Geant4,包括各种辅助工具(QT、Cmake、Visual Studio)的下载安装,环境变量的配置,以及example的生成等。
【BLE系列-第六篇】GATT解析:属性、特征、描述符的逻辑关系
本文系统介绍了BLE协议中的ATT和GATT机制。ATT以"属性"为基本数据单元,包含UUID、Handle、权限和Value四个要素。GATT则在ATT基础上构建了服务、特征和描述符的层次结构:服务(UUID:0x2800/0x2801)通过声明属性标识,特征声明(UUID:0x2803)指向特征值(UUID:0x2Axx或自定义),描述符(UUID:0x2900~0x290F)提供附加信息。GATT复用ATT发现机制,通过定义特定UUID语义实现服务发现和特征管理。这种设计使BLE设
豆瓣评论自动抓取脚本:完整安装与使用指南
如需修改默认参数,可通过浏览器控制台调用:Javascript编辑1// 仅抓取10页,延迟1500-3000毫秒6});参数说明参数默认值说明合理范围maxPages50最大抓取页数1-100(建议)minDelay800页间最小延迟(毫秒)500-5000maxDelay2200页间最大延迟(毫秒)1000-10000法律建议:为降低法律风险,建议将maxPages设为10以内,minDelay设为1500以上技术的力量在于为善。
Claude skill-creator插件深度解析:从创建到优化的完整技能工程化体系
摘要:skill-creator是Anthropic推出的Claude技能开发插件,提供从创建到优化的全流程工程化支持。其核心架构采用渐进式披露机制和多Agent协作模式,包含Grader、Analyzer等专业评估组件。该插件支持自动化评测系统,通过测试用例管理、并行执行和结果聚合实现技能验证;提供迭代优化算法,基于数据驱动改进技能性能。典型应用场景包括标准化技能开发、自动化测试验证和触发优化,显著降低开发门槛并提升技能质量。
史上最全 Python 爬虫抓取的技巧总结
如此,把上述所有小技巧都糅合起来就和我目前的私藏最终版的Fetcher类相差不远了,它支持多线程,gzip/deflate压缩,超时设置,自动重试,设置栈大小,自动登录等功能;代码简单,使用方便,性能也不俗,可谓居家旅行,杀人放火,咳咳,之必备工具。之所以说和最终版差得不远,是因为最终版还有一个保留功能“马甲术”:多代理自动选择。看起来好像仅仅是一个random.choice的区别,其实包含了代理获取,代理验证,代理测速等诸多环节,这就是另一个故事了。
Allegro 给元器件PCB封装库添加3D模型详细步骤
从上面视图可以看到模型跟PCB 库的方向是对了,但是位置偏下,且在PCB封装库后面,我们下面需要做的就是把模型往上移、往前移。首先将元器件3D模型文件放在封装库的目录下(也可以单独新建一个模型库文件夹),注意3D文件必须是Step格式。Transparent: 选择透视的对象,可以是模型、也可以是PCB封装,或者两种都透视。在左边搜索要添加的3D模型的文件(注意是在* 星号前面输入文件名),按回车即可找到。同样的,接下来需要往Y 负方向移,即左移,一边调整一边观察视图。
SNAP计算哨兵2号的LAI/FVC/FAPAR
SNAP的计算LAI方法是基于PROSAIL模型,集成的模块,很方便。首先要下载SNAP软件,下载步骤见。
bat脚本抓取android日志
本文介绍了两种通过bat脚本抓取Android设备日志的方法。第一种将日志保存到Windows本地,包括:1)抓取特定PID的应用程序日志;2)获取系统crash日志;3)过滤特定tag的日志。第二种方法将日志保存到Android设备存储卡中,同样包含上述三种日志类型,并会自动创建日志目录和删除旧文件。两种方法都使用adb命令,支持UTF-8编码输出,适合开发人员收集和分析Android系统及应用程序的运行日志。
【深度学习新浪潮】AI 智能眼镜关键视觉技术、技术栈及开源项目全解析
Meta新款智能眼镜在演示中暴露出的AI误判和延迟问题,揭示了端侧视觉与多模态算法落地的核心瓶颈。本文从算法工程视角解析了AI智能眼镜的三大关键技术:感知增强(多帧降噪、HDR成像)、场景解析(轻量化目标检测、语义分割)和空间定位(视觉SLAM、ToF辅助),并梳理了完整的技术栈架构,包括硬件适配、驱动优化和框架选型。文章还提供了高价值开源项目参考,如OpenXR和ORB-SLAM3,为端侧视觉算法落地提供实操指南,助力开发者攻克算力约束下的实时性、精度和功耗平衡难题。
Shell脚本 | 抓取log文件
在安卓应用的测试过程中,遇到 Crash 或者 ANR 后,想必大家都会通过 adb logcat 命令来抓取日志定位问题。如果直接使用 logcat 命令的话,默认抓取出的 log 文件包含安卓运行时产生的所有日志,给快速定位问题增加了时间成本。 这个问题可以通过一个简单的 Shell 脚本来解决,依然只有区区 20 行左右的代码。 脚本的编写思路是这样的: 1、通过 date 命令获...
Allegro输出光绘文件规范
添加钻孔表的具体步骤为:1.通过屏幕右边的Visibility选项的Views列表,将Drill层打开2.将Visibility选项中的PIN和Via选项都选中,见下图所示: 参数设好之后关闭NC Drill/Parameters窗口,输出数控机床钻孔文件的命令菜单为:Manufacture=>NC=>NC Drill…,打开的窗口如下: 输出数控机床钻孔文件的具体步骤为: 上图是光绘输出的层控制窗口,还有一个窗口是输出参数的控制窗口,我们通过点击上图的第二个列表项General Parameters来
复分析 阿尔福斯(Ahlfors) 第三版答案 英文
答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案
抓取指定网站上的所有图片的Python脚本
网络爬虫(Web Crawler)是一种自动提取网页信息的程序,它可以从互联网上抓取数据并存储到本地或数据库中。网络爬虫的工作原理是通过生成URL种子列表,不断访问和下载网页内容,经过处理后存储到数据库中。网络爬虫的类型主要包括通用网络爬虫、聚焦网络爬虫和增量式网络爬虫。中文分词技术在网络爬虫中的应用主要是对抓取的文本数据进行有效的分词处理,以便于后续的信息检索和数据分析。本文详细介绍了如何使用Python编写一个脚本来自动抓取指定网站上的所有图片,并深入探讨了相关的技术细节和实现原理。
C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片
基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正
shell脚本写的一个图片抓取器
和大家分享下一个shell脚本写的图片抓取器,该程序来自《Linux Shell脚本攻略》。记得去年找工作面试时,听到一位同学说自己非常喜欢linux,我相信他说的是真的,我觉得喜欢linux的人很大的快乐来自shell脚本,因为它能够整合linux上的各种资源干大事。 用法:复制以下代码,命名为img_downloader.sh。使用时在shell下输入 ./img_downloader.sh
蓝牙模块HM-10手册
蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。
VC中sqlite的使用
在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示
cshell脚本抓取文件
一个cshell脚本#!/bin/bash touch regexcl.list ##cshell 列表的用法 folder_list=(/vobs/cp_rtl-host/test/src/toplevel/lmu \ /vobs/cp_rtl-host/test/src/toplevel/host_spcu ) #foreach ({folder_list[i]}
小白教程:Python 怎么写一个抓取小说的自动化脚本
本文介绍如何使用Python编写一个简单的小说抓取脚本,适合零基础用户。主要内容包括:1.准备工作:安装Python解释器和requests、BeautifulSoup库;2.抓取原理:通过获取章节列表、下载内容并保存到本地三个步骤实现;3.详细代码实现:包括获取章节列表、下载章节内容和保存到本地的完整代码;4.使用说明:如何修改URL和选择器参数;5.常见问题解决方法。文章还提醒读者注意法律和道德问题,遵守网站规则,并建议进阶学习方向。该脚本可帮助用户自动下载整本小说,适合个人离线阅读使用。
python抓取oracle数据,python爬虫,抓取oracle-base上的一些常用脚本
以下利用python实现在http://www.oracle-base.com/dba上抓取上有的数据库常用脚本,时间关系,写的比较粗糙,分享给大家,希望大家一起进步。# -*- coding: utf-8 -*-#---------------------------------------# 程序:抓取http://www.oracle-base.com/dba上的脚本# 版本:0.1...
使用 Python 脚本和蜘蛛自动进行 Web 抓取
Scrapy 是一个免费的开源应用程序框架,用于爬取网站和提取结构化数据,可用于各种事情,如数据挖掘、研究、信息处理或历史档案。它是一种复制形式,其中从 Web 收集和复制特定数据,通常到中央本地数据库或电子表格中,以供以后检索或分析。获取后,即可进行提取。网络抓取用于联系人抓取,并作为用于网络索引、网络挖掘和数据挖掘、在线价格变化监控和价格比较、产品评论抓取(观看竞争对手)、收集房地产列表、天气数据监控、网站更改检测、研究、跟踪在线状态和声誉、网络混搭和网络数据集成的应用程序的组件。需要计算机和互联网。
使用Python脚本抓取aws所有的IP地址
为了满足客户业务需求,需要抓取AWS新加坡所有IP地址来设定路由。AWS官网有专门的链接列出所有IP地址,先只需要利用脚本筛选出新加坡地址就OK。 所有IP地址链接:https://ip-ranges.amazonaws.com/ip-ranges.json 上述链接中“region”分别代表的意思:https://docs.aws.amazon.com/zh_cn/AWSEC2/latest...
抓取网页图片的脚本(javascript)
抓取网页图片的脚本(javascript) 本文地址: http://blog.youkuaiyun.com/caroline_wendy/article/details/24172223 脚本内容 (没有换行): javascript:void(function(g,d,m,s){g[m]?(g[m].c=1,g[m]()):!d[m]&&(d.getElem...
shell脚本抓取网页信息
利用shell脚本分析网站数据 # define url time=$(date +%F) mtime=$(date +%T) file=/abc/shell/abc/abc_$time.log http=https://abc.com/abc/abc.do key='tender_sum' log_file=/abc/shell/abc/remind.log check_...
【Linux】通过脚本抓取yum的试试,都访问了哪些域名
更精准的tcpdump命令格式-nn-vvv。
抓取网页的脚本 【修复】
之前张耀老师的网页脚本由于51cto升级,课程列表页面改用javascript失效了笔者发现视频课程页面右边的列表都为静态化后的视频课程地址,遂将老师初始版本的脚本进行了修改,在对视频课程页面使用时结果正常,遂将及修改后的脚本和部分注释发上来供大家研究[root@m01scripts]#cathtml_to_table.sh #!/bin/bash #oldboy...
1236



被折叠的 条评论
为什么被折叠?



