curl 抓取网页

curl 抓取网页

curl 抓取网页(我另外一个博客中有一个 )

网站优化优采云 发表了文章 • 0 个评论 • 65 次浏览 • 2021-10-02 00:19 • 来自相关话题

  curl 抓取网页(我另外一个博客中有一个
)
  有一个我自己写的源代码,用于在另一个博客中抓取其他网页。之前调试的时候没有问题,发布后一段时间内容也没有问题,但是突然发现爬虫功能不行了。右键查看源文件,看到获取的数据是空的。
  我查看了我的源代码并在服务器上调试了几次。我什至重新抓包,查看了对方的网站数据。
  一开始以为是我服务器的IP被对方的服务器屏蔽了,于是把源码发给另一个朋友调试,发现不是这个原因。
  然后我怀疑对方是不是更新了算法,加密了程序,但是我在源码中对获取数据的模块变量做了echo输出,然后才发现获取的数据是乱码。
  
  第一眼看到乱码,还以为是对方的开发者加密了数据,于是放弃了几天。
  今天在源码中尝试对获取到的数据进行字符集转换,但是不管怎么转换,都是乱码。
  找了一天,终于在C#程序员里面写了一个idea。
  原来问题出在我的帖子的标题数据中。我在源代码中添加了一行'Accept-Encoding:gzip, deflate, br'。删除后问题解决,因为是gzip压缩导致的乱码。
  $cars = $GLOBALS['ua'];
$header = array(
"POST {$ii} HTTP/2.0",
"Host: {$web} ",
"filename: {$id} ",
"Referer: {$ii} ",
"Content-Type: text/html",
'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,video/webm,video/ogg,video/*;q=0.9,application/ogg;q=0.7,audio/*;q=0.6,*/*;q=0.5,application/signed-exchange;v=b3',
'Accept-Encoding:gzip, deflate, br',
'Accept-Language:zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2',
'Connection:keep-alive',
"Cookie: {$cars[1]}",
"User-Agent: {$cars[0]}",
"X-FORWARDED-FOR:180.149.134.142",
"CLIENT-IP:180.149.134.142",
);
echo "header: {$header[0]}
{$header[1]}
{$header[2]}
{$header[3]}
{$header[4]}
{$header[5]}
{$header[6]}
{$header[7]}
{$header[8]}
{$header[9]}
{$header[10]}
{$header[11]}
{$header[12]}
{$header[13]}
";
return $header;
  通过删除以下行来解决问题。
  'Accept-Encoding:gzip, deflate, br',
   查看全部

  curl 抓取网页(我另外一个博客中有一个
)
  有一个我自己写的源代码,用于在另一个博客中抓取其他网页。之前调试的时候没有问题,发布后一段时间内容也没有问题,但是突然发现爬虫功能不行了。右键查看源文件,看到获取的数据是空的。
  我查看了我的源代码并在服务器上调试了几次。我什至重新抓包,查看了对方的网站数据。
  一开始以为是我服务器的IP被对方的服务器屏蔽了,于是把源码发给另一个朋友调试,发现不是这个原因。
  然后我怀疑对方是不是更新了算法,加密了程序,但是我在源码中对获取数据的模块变量做了echo输出,然后才发现获取的数据是乱码。
  http://www.myzhenai.com.cn/wp- ... 4.png 300w, http://www.myzhenai.com.cn/wp- ... 8.png 768w, http://www.myzhenai.com.cn/wp- ... 6.png 1536w, http://www.myzhenai.com.cn/wp- ... a.png 1907w" />
  第一眼看到乱码,还以为是对方的开发者加密了数据,于是放弃了几天。
  今天在源码中尝试对获取到的数据进行字符集转换,但是不管怎么转换,都是乱码。
  找了一天,终于在C#程序员里面写了一个idea。
  原来问题出在我的帖子的标题数据中。我在源代码中添加了一行'Accept-Encoding:gzip, deflate, br'。删除后问题解决,因为是gzip压缩导致的乱码。
  $cars = $GLOBALS['ua'];
$header = array(
"POST {$ii} HTTP/2.0",
"Host: {$web} ",
"filename: {$id} ",
"Referer: {$ii} ",
"Content-Type: text/html",
'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,video/webm,video/ogg,video/*;q=0.9,application/ogg;q=0.7,audio/*;q=0.6,*/*;q=0.5,application/signed-exchange;v=b3',
'Accept-Encoding:gzip, deflate, br',
'Accept-Language:zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2',
'Connection:keep-alive',
"Cookie: {$cars[1]}",
"User-Agent: {$cars[0]}",
"X-FORWARDED-FOR:180.149.134.142",
"CLIENT-IP:180.149.134.142",
);
echo "header: {$header[0]}
{$header[1]}
{$header[2]}
{$header[3]}
{$header[4]}
{$header[5]}
{$header[6]}
{$header[7]}
{$header[8]}
{$header[9]}
{$header[10]}
{$header[11]}
{$header[12]}
{$header[13]}
";
return $header;
  通过删除以下行来解决问题。
  'Accept-Encoding:gzip, deflate, br',
  http://www.myzhenai.com.cn/wp- ... 3.png 300w, http://www.myzhenai.com.cn/wp- ... 8.png 768w, http://www.myzhenai.com.cn/wp- ... 6.png 1536w, http://www.myzhenai.com.cn/wp- ... 1.png 1887w" />

curl 抓取网页(使用PHP的cURL库可以简单和有效地去抓网页。)

网站优化优采云 发表了文章 • 0 个评论 • 99 次浏览 • 2021-09-28 21:06 • 来自相关话题

  curl 抓取网页(使用PHP的cURL库可以简单和有效地去抓网页。)
  使用 PHP 的 cURL 库来简单有效地抓取网页。你只需要运行一个脚本,然后分析你抓取的网页,然后你就可以通过编程的方式得到你想要的数据。无论您是想从链接中获取部分数据,还是获取 XML 文件并将其导入数据库,即使只是获取网页内容,cURL 都是一个强大的 PHP 库。本文主要介绍如何使用这个PHP库。
  启用卷曲设置
  首先我们要先判断我们的PHP是否启用了这个库,可以通过php_info()函数来获取这个信息。
  ﹤?php
phpinfo();
?﹥
  如果在网页上可以看到如下输出,说明cURL库已经开启。
  如果你看到它,那么你需要设置你的 PHP 并启用这个库。如果你是windows平台,很简单,你需要改变你的php.ini文件的设置,找到php_curl.dll,去掉前面的分号。如下:
  //取消下在的注释
extension=php_curl.dll
  如果你在 Linux 下,那么你需要重新编译你的 PHP。编辑时需要开启编译参数——在configure命令中添加“--with-curl”参数。
  一个小例子
  如果一切就绪,这里有一个小程序:
  ﹤?php
  // 初始化一个 cURL 对象
  $curl = curl_init();
  // 设置你需要爬取的网址
  curl_setopt($curl, CURLOPT_URL,'');
  // 设置标题
  curl_setopt($curl, CURLOPT_HEADER, 1);
  // 设置cURL参数,询问结果是保存在字符串中还是输出到屏幕上。
  curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
  // 运行 cURL 并请求一个网页
  $data = curl_exec($curl);
  // 关闭 URL 请求
  curl_close($curl);
  // 显示获取的数据
  var_dump($data);
  如何发布数据
  上面是抓取网页的代码,下面是到某个网页的POST数据。假设我们有一个处理表单的URL,可以接受两个表单域,一个是电话号码,一个是短信内容。
  ﹤?php
$phoneNumber = '13912345678';
$message = 'This message was generated by curl and php';
$curlPost = 'pNUMBER=' . urlencode($phoneNumber) . '&MESSAGE=' . urlencode($message) . '&SUBMIT=Send';
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'http://www.example.com/sendSMS.php');
curl_setopt($ch, CURLOPT_HEADER, 1);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $curlPost);
$data = curl_exec();
curl_close($ch);
?﹥
  从上面的程序可以看出,CURLOPT_POST是用来设置HTTP协议的POST方法而不是GET方法的,然后CURLOPT_POSTFIELDS是用来设置POST数据的。
  关于代理服务器
  以下是如何使用代理服务器的示例。请注意高亮的代码,代码很简单,我就不多说了。
  ﹤?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'http://www.example.com');
curl_setopt($ch, CURLOPT_HEADER, 1);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_HTTPPROXYTUNNEL, 1);
curl_setopt($ch, CURLOPT_PROXY, 'fakeproxy.com:1080');
curl_setopt($ch, CURLOPT_PROXYUSERPWD, 'user:password');
$data = curl_exec();
curl_close($ch);
?﹥
  关于 SSL 和 Cookie 查看全部

  curl 抓取网页(使用PHP的cURL库可以简单和有效地去抓网页。)
  使用 PHP 的 cURL 库来简单有效地抓取网页。你只需要运行一个脚本,然后分析你抓取的网页,然后你就可以通过编程的方式得到你想要的数据。无论您是想从链接中获取部分数据,还是获取 XML 文件并将其导入数据库,即使只是获取网页内容,cURL 都是一个强大的 PHP 库。本文主要介绍如何使用这个PHP库。
  启用卷曲设置
  首先我们要先判断我们的PHP是否启用了这个库,可以通过php_info()函数来获取这个信息。
  ﹤?php
phpinfo();
?﹥
  如果在网页上可以看到如下输出,说明cURL库已经开启。
  如果你看到它,那么你需要设置你的 PHP 并启用这个库。如果你是windows平台,很简单,你需要改变你的php.ini文件的设置,找到php_curl.dll,去掉前面的分号。如下:
  //取消下在的注释
extension=php_curl.dll
  如果你在 Linux 下,那么你需要重新编译你的 PHP。编辑时需要开启编译参数——在configure命令中添加“--with-curl”参数。
  一个小例子
  如果一切就绪,这里有一个小程序:
  ﹤?php
  // 初始化一个 cURL 对象
  $curl = curl_init();
  // 设置你需要爬取的网址
  curl_setopt($curl, CURLOPT_URL,'');
  // 设置标题
  curl_setopt($curl, CURLOPT_HEADER, 1);
  // 设置cURL参数,询问结果是保存在字符串中还是输出到屏幕上。
  curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
  // 运行 cURL 并请求一个网页
  $data = curl_exec($curl);
  // 关闭 URL 请求
  curl_close($curl);
  // 显示获取的数据
  var_dump($data);
  如何发布数据
  上面是抓取网页的代码,下面是到某个网页的POST数据。假设我们有一个处理表单的URL,可以接受两个表单域,一个是电话号码,一个是短信内容。
  ﹤?php
$phoneNumber = '13912345678';
$message = 'This message was generated by curl and php';
$curlPost = 'pNUMBER=' . urlencode($phoneNumber) . '&MESSAGE=' . urlencode($message) . '&SUBMIT=Send';
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'http://www.example.com/sendSMS.php');
curl_setopt($ch, CURLOPT_HEADER, 1);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $curlPost);
$data = curl_exec();
curl_close($ch);
?﹥
  从上面的程序可以看出,CURLOPT_POST是用来设置HTTP协议的POST方法而不是GET方法的,然后CURLOPT_POSTFIELDS是用来设置POST数据的。
  关于代理服务器
  以下是如何使用代理服务器的示例。请注意高亮的代码,代码很简单,我就不多说了。
  ﹤?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'http://www.example.com');
curl_setopt($ch, CURLOPT_HEADER, 1);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_HTTPPROXYTUNNEL, 1);
curl_setopt($ch, CURLOPT_PROXY, 'fakeproxy.com:1080');
curl_setopt($ch, CURLOPT_PROXYUSERPWD, 'user:password');
$data = curl_exec();
curl_close($ch);
?﹥
  关于 SSL 和 Cookie

curl 抓取网页( 其它命令参数用法,同url网址方式,和wget用法)

网站优化优采云 发表了文章 • 0 个评论 • 57 次浏览 • 2021-09-27 07:21 • 来自相关话题

  curl 抓取网页(
其它命令参数用法,同url网址方式,和wget用法)
  
  其他命令参数的用法与url方法相同,这里不再赘述。
  更多curl和wget的用法如ftp协议、迭代子目录等,可以查看man中的帮助手册
  知识拓展:
  在国内,由于某些原因,一般很难直接访问一些敏感的海外网站,需要通过VPN或代理服务器访问。
  如果校园网和教育网有IPv6,可以通过免费代理访问facebook、twitter、六维空间等网站
  其实除了VPN和IPv6+代理方式,普通用户还有其他方式访问国外网站
  这里有两个著名的自由球员网站:
  (全球数十个国家的自由代理,每日更新)
  (通过设置端口类型、代理类型、国家名称过滤)
  curl 项目示例
  使用curl+free agent实现全球12个国家googleplay游戏排名的网页抓取和趋势图查询(抓取网页模块全部用Shell编写,核心代码1000行左右)
  爬取google play游戏排名网页,首先需要分析网页的特点和规律:
  1、Google play游戏排名页面是“总分”格式,即一个页面URL显示了几个排名(比如24),这样的页面有几个构成了所有游戏的总排名
  2、 在每个页面的URL中,点击每个单独的游戏链接可以查看游戏的属性信息(如评分星级、发布日期、版本号、SDK版本号、游戏类别、下载量等)
  需要解决的问题:
  1、如何抓取所有游戏的总排名?
  2、抓取整体排名后,如何拼接网址抓取各个单独的游戏页面?
  3、获取各个单独的游戏网页后,如何提取网页中游戏的属性信息(即评分星级、发布日期...)?
  4、提取出各个游戏的属性信息后,如何保存(mysql)、生成日报(html)、发送日报(email)?
  5、根据抓取到的游戏属性信息资源,如何查询贵公司的游戏排名(JSP)以及如何清晰的展示游戏排名(JFreeChart图表)?
  6、 更难的是谷歌玩游戏排名没有统一的全球排名。Google 使用本地化策略。数十个国家/地区都有自己的一套排名算法和规则。如何在12个国家实现游戏排名?
  设计方案及技术选择
  分析了上述问题和需求后,如何一一解决并分解,这是我们需要思考、设计和解决的问题(模块流程和技术实现)?
  基于以上分析提出的问题,将一一进行模块设计和技术方案选择如下:
  
  1、为了抓取12个国家的游戏排名,需要分别租用12个国家的代理服务器来抓取各个国家的游戏排名(12个国家的游戏排名算法和语言是不同,包括中文、英文、日文、俄文、西班牙文...)
  2、 抓取网页,使用curl+proxy代理;提取下载的网页信息,使用awk文本分析工具(需要对html语法tag、id等元素有很好的理解才能准确使用awk提取游戏属性信息)
  3、由于IP代理筛选系统、网页抓取程序、游戏属性信息提取等模块都是由脚本完成的,为了保持编程语言的一致性,数据库创建和记录插入也实现了通过 shell 脚本。
  4、 抓取的每款游戏的属性信息,采用html+table的网页形式展示,清晰直观。一个shell脚本用来拼接html字符串(table+tr+td+info)
  5、 生成的html网页会以每日邮件的形式定期发送给产品总监、PM、RD、QA,了解公司发布的游戏排行榜,以及上升最快、最受欢迎的游戏趋势在世界上
  6、 开发JSP网页查询系统,根据输入的游戏名或游戏包名查询某款游戏的排名和趋势,并在趋势图下显示该游戏的所有详细属性信息
  模块技术实现
  1、IP代理过滤
  成本考虑,每个国家租用代理服务器(VPN),以市场最低价1000元/月计算,12000元一年,12个国家的总费用为12x12000=144,000,也就是大约140,000/年的VPN租用需要收费
  基于成本考虑,我后来通过对代理服务器和免费ip的深入研究,提出设计开发一套免费ip代理服务器筛选系统,抓取12个国家的游戏排名。
  免费代理IP主要来自上一篇博客介绍的两个网站:和
  IP代理筛选系统,由于文本预处理和筛选逻辑实现的复杂性,将在下一篇博文中单独介绍
  2、 抓取排名页面
  仔细分析google play游戏排名页面,发现有一定的规律可循:
  第一页的Top24 URL:
  第二页的Top48 URL
  第三页的Top72 URL
  此时,观察每个页面URL的最后一串?start=24&num=24,你已经找到了模式^_^ 其实网页的第一页是从start=0开始的,也可以写成:
  第一页的Top24 URL
  根据上面的规则,可以使用curl+proxy通过循环拼接字符串(start='expr $start + 24')来爬取排名网页
  3、提取游戏链接
  排名页面,每个页面收录24个游戏网址超链接,如何提取这24个游戏网址超链接?
  当时就考虑用xml解析,因为html是一种分层组织的类似xml的格式,但是有些网页并不是所有标准的html格式(比如左括号后没有右括号闭包),这样会导致xml不被正确解析
  后来结合自己学到的html和js知识,分析了爬行排名网页的内容结构,发现每个游戏链接前面都有一个独特的具体格式如下(以篮球投篮为例):
  Basketball Shoot
  这样就可以通过awk顺利提取附近的文本内容,具体实现如下:
  # split url_24
page_key='class="title"'
page_output='output_page.log'
page_output_url_start='https://play.google.com/store/apps/'
page_output_url='output_top800_url.log'
function page_split(){
grep $page_key $(ls $url_output* | sort -t "_" -k6 -n) > tmp_page_grepURL.log # use $url_output
awk -F'[]' '{for(i=1;i> $log
echo "================= $date ================" >> $log


# mysql database and table to create
HOST='localhost'
PORT='3306'
USER='root'
PWD='xxxxxx'
DBNAME='top800'
TABLENAME='gametop800'

mysql_login=''
mysql_create_db=''
mysql_create_table=''


function mysql_create(){
echo "login mysql $HOST:$PORT ..." >> $log
mysql_login="mysql -h $HOST -P $PORT -u $USER -p$PWD" # mysql -h host -P port -u root -p pwd
echo | ${mysql_login}
if [ $? -ne 0 ]; then
echo "login mysql ${HOST}:${PORT} failed.." >> $log
exit 1
else
echo "login mysql ${HOST}:${PORT} success!" >> $log
fi

echo "create database $DBNAME ..." >> $log
mysql_create_db="create database if not exists $DBNAME"
echo ${mysql_create_db} | ${mysql_login}
if [ $? -ne 0 ]; then
echo "create db ${DBNAME} failed.." >> $log
else
echo "create db ${DBNAME} success!" >> $log
fi

echo "create table $TABLENAME ..." >> $log
mysql_create_table="create table $TABLENAME(
id char(50) not null,
url char(255),
top int,
name char(100),
category char(50),
rating char(10),
ratingcount char(20),
download char(30),
price char(20),
publishdate char(20),
version char(40),
filesize char(40),
requireandroid char(40),
contentrating char(40),
country char(10) not null,
dtime date not null default \"2011-01-01\",
primary key(id, country, dtime)
)"

echo ${mysql_create_table} | ${mysql_login} ${DBNAME}
if [ $? -ne 0 ]; then
echo "create table ${TABLENAME} fail..." >> $log
else
echo "create table ${TABLENAME} success!" >> $log
fi
}
  脚本功能说明:
  首先登录mysql数据库,判断mysql服务器、端口号、用户名、密码是否正确。如果不正确,则登录失败退出(exit1);如果正确,则登录成功,继续下一步
  然后,创建数据库名,判断数据库是否存在,如果不存在,则创建;如果存在,继续下一步(注意:创建数据库时,需要验证是否登录数据库成功,否则无法操作)
  最后创建数据库表,首先设计数据库表的各个字段,然后创建数据库表,具体判断方法与创建数据库名称相同
  遍历游戏属性信息文本,全部插入mysql数据库统一存储管理
  # Author : yanggang
# Datetime : 2011.10.24 21:45:09
# ============================================================
#!/bin/sh


# insert mysql
file_input='output_top800_url_page'
file_output='sql_output'

HOST='localhost'
PORT='3306'
USER='root'
PWD='xxxxxx'
DBNAME='top800'
TABLENAME='gametop800'

col_id=''
col_url=''
col_top=1
col_name=''
col_category=''
col_rating=''
col_ratingcount=''
col_download=''
col_price=''
col_publishdate=''
col_version=''
col_filesize=''
col_requireandroid=''
col_contentrating=''
col_country=''
col_dtime=''

sql_insert='insert into gametop800 values("com.mobile.games", "url", 3, "minesweeping",
"games", "4.8", "89789", "1000000-5000000000", "free", "2011-2-30", "1.2.1", "1.5M", "1.5 up", "middle", "china", "2011-10-10")'

function mysql_insert(){
rm -rf $file_output
touch $file_output

DBNAME=$1
col_dtime=$2
col_country=$3
echo 'col_dtime========='$col_dtime

while read line
do
col_id=$(echo $line | cut -f 1 -d "%" | cut -f 1 -d "&" | cut -f 2 -d "=")
col_url=$(echo $line | cut -f 1 -d "%")
col_name=$(echo $line | cut -f 2 -d "%")
col_category=$(echo $line | cut -f 3 -d "%")
col_rating=$(echo $line | cut -f 4 -d "%")
col_ratingcount=$(echo $line | cut -f 5 -d "%")
col_download=$(echo $line | cut -f 6 -d "%")
col_price=$(echo $line | cut -f 7 -d "%")
col_publishdate=$(echo $line | cut -f 8 -d "%")
col_version=$(echo $line | cut -f 9 -d "%")
col_filesize=$(echo $line | cut -f 10 -d "%")
col_requireandroid=$(echo $line | cut -f 11 -d "%")
col_contentrating=$(echo $line | cut -f 12 -d "%")


sql_insert='insert into '$TABLENAME' values('"\"$col_id\", \"$col_url\", $col_top,
\"$col_name\", \"$col_category\", \"$col_rating\", \"$col_ratingcount\", \"$col_download\",
\"$col_price\", \"$col_publishdate\", \"$col_version\", \"$col_filesize\", \"$col_requireandroid\",
\"$col_contentrating\", \"$col_country\", \"$col_dtime\""');'

echo $sql_insert >> $file_output
mysql -h $HOST -P $PORT -u $USER -p$PWD -e "use $DBNAME; $sql_insert"

col_top=`expr $col_top + 1`
done < $file_input
}
  脚本功能说明:
  插入数据库脚本比较简单,主要实现两个功能:游戏排名号(col_top)和数据库语句插入($sql_insert)
  通过while read line循环,读取模块5提取的游戏属性信息文本文件,分割每一行得到对应的字段(cut -f 2 -d "%"),赋值给insert语句(sql_insert)
  最后通过mysql -h $HOST -P $PORT -u $USER-p$PWD -e "use $DBNAME; $sql_insert",登录mysql数据库,执行插入语句$sql_insert
  7、生成HTML报告
  shell 通过连接字符串 table + tr + td + info 来生成 html web 报告。详情请参考我之前的博客:shell将txt转换为html
  8、通过电子邮件发送报告
  邮件发送模块主要采用/usr/bin/mutt的方式。邮件正文显示html报告(默认为美国),其他国家以附件形式发送。详细请参考我之前的博客:linuxshell发送邮件附件
  使用 crontab 命令定期发送电子邮件。具体配置和使用可以参考我之前写的博客:linux定时运行命令script-crontab
  9、网页查询报告
  使用JSP提取MySQL中存储的游戏属性信息,循环生成游戏排名的网页信息,请参考我之前的博客:LinuxJSP连接MySQL数据库
  10、 排名趋势图
  趋势图,使用第三方JFreeChart图表生成工具,请参考我之前的博客:JFreeChart学习实例
  游戏排名趋势图生成后,需要嵌套到JSP网页中进行展示。完整的排名趋势图请参考我之前的博客:JFreeChart Project Example
  自动化主控制脚本
  12国游戏排名系统,免费ip代理过滤——“网络爬虫——”数据库保存——“生成排名报告——”及时发送邮件报告——“游戏排名查询——”趋势图生成
  都实现了整个流程的自动化,以下是各个模块的脚本实现和功能说明:
  
  通过配置服务器的crontab定时运行进程命令,在早上00:01:00(早上0:01:00),主控脚本top10_all.sh会自动启动。
  每天生成的日报使用主控脚本自动生成当天的文件夹,保存当天的抓包数据、分析数据、结果数据,如下图所示:
  
  注:以上文件夹数据为去年测试数据的副本,排名并非本人笔记本截图
  因为通过远程代理爬取12个国家排名前800的TOP800需要消耗网络资源、内存资源和时间,严重影响我的上网体验~~~~(&gt;_ 查看全部

  curl 抓取网页(
其它命令参数用法,同url网址方式,和wget用法)
  
  其他命令参数的用法与url方法相同,这里不再赘述。
  更多curl和wget的用法如ftp协议、迭代子目录等,可以查看man中的帮助手册
  知识拓展:
  在国内,由于某些原因,一般很难直接访问一些敏感的海外网站,需要通过VPN或代理服务器访问。
  如果校园网和教育网有IPv6,可以通过免费代理访问facebook、twitter、六维空间等网站
  其实除了VPN和IPv6+代理方式,普通用户还有其他方式访问国外网站
  这里有两个著名的自由球员网站:
  (全球数十个国家的自由代理,每日更新)
  (通过设置端口类型、代理类型、国家名称过滤)
  curl 项目示例
  使用curl+free agent实现全球12个国家googleplay游戏排名的网页抓取和趋势图查询(抓取网页模块全部用Shell编写,核心代码1000行左右)
  爬取google play游戏排名网页,首先需要分析网页的特点和规律:
  1、Google play游戏排名页面是“总分”格式,即一个页面URL显示了几个排名(比如24),这样的页面有几个构成了所有游戏的总排名
  2、 在每个页面的URL中,点击每个单独的游戏链接可以查看游戏的属性信息(如评分星级、发布日期、版本号、SDK版本号、游戏类别、下载量等)
  需要解决的问题:
  1、如何抓取所有游戏的总排名?
  2、抓取整体排名后,如何拼接网址抓取各个单独的游戏页面?
  3、获取各个单独的游戏网页后,如何提取网页中游戏的属性信息(即评分星级、发布日期...)?
  4、提取出各个游戏的属性信息后,如何保存(mysql)、生成日报(html)、发送日报(email)?
  5、根据抓取到的游戏属性信息资源,如何查询贵公司的游戏排名(JSP)以及如何清晰的展示游戏排名(JFreeChart图表)?
  6、 更难的是谷歌玩游戏排名没有统一的全球排名。Google 使用本地化策略。数十个国家/地区都有自己的一套排名算法和规则。如何在12个国家实现游戏排名?
  设计方案及技术选择
  分析了上述问题和需求后,如何一一解决并分解,这是我们需要思考、设计和解决的问题(模块流程和技术实现)?
  基于以上分析提出的问题,将一一进行模块设计和技术方案选择如下:
  
  1、为了抓取12个国家的游戏排名,需要分别租用12个国家的代理服务器来抓取各个国家的游戏排名(12个国家的游戏排名算法和语言是不同,包括中文、英文、日文、俄文、西班牙文...)
  2、 抓取网页,使用curl+proxy代理;提取下载的网页信息,使用awk文本分析工具(需要对html语法tag、id等元素有很好的理解才能准确使用awk提取游戏属性信息)
  3、由于IP代理筛选系统、网页抓取程序、游戏属性信息提取等模块都是由脚本完成的,为了保持编程语言的一致性,数据库创建和记录插入也实现了通过 shell 脚本。
  4、 抓取的每款游戏的属性信息,采用html+table的网页形式展示,清晰直观。一个shell脚本用来拼接html字符串(table+tr+td+info)
  5、 生成的html网页会以每日邮件的形式定期发送给产品总监、PM、RD、QA,了解公司发布的游戏排行榜,以及上升最快、最受欢迎的游戏趋势在世界上
  6、 开发JSP网页查询系统,根据输入的游戏名或游戏包名查询某款游戏的排名和趋势,并在趋势图下显示该游戏的所有详细属性信息
  模块技术实现
  1、IP代理过滤
  成本考虑,每个国家租用代理服务器(VPN),以市场最低价1000元/月计算,12000元一年,12个国家的总费用为12x12000=144,000,也就是大约140,000/年的VPN租用需要收费
  基于成本考虑,我后来通过对代理服务器和免费ip的深入研究,提出设计开发一套免费ip代理服务器筛选系统,抓取12个国家的游戏排名。
  免费代理IP主要来自上一篇博客介绍的两个网站:和
  IP代理筛选系统,由于文本预处理和筛选逻辑实现的复杂性,将在下一篇博文中单独介绍
  2、 抓取排名页面
  仔细分析google play游戏排名页面,发现有一定的规律可循:
  第一页的Top24 URL:
  第二页的Top48 URL
  第三页的Top72 URL
  此时,观察每个页面URL的最后一串?start=24&amp;num=24,你已经找到了模式^_^ 其实网页的第一页是从start=0开始的,也可以写成:
  第一页的Top24 URL
  根据上面的规则,可以使用curl+proxy通过循环拼接字符串(start='expr $start + 24')来爬取排名网页
  3、提取游戏链接
  排名页面,每个页面收录24个游戏网址超链接,如何提取这24个游戏网址超链接?
  当时就考虑用xml解析,因为html是一种分层组织的类似xml的格式,但是有些网页并不是所有标准的html格式(比如左括号后没有右括号闭包),这样会导致xml不被正确解析
  后来结合自己学到的html和js知识,分析了爬行排名网页的内容结构,发现每个游戏链接前面都有一个独特的具体格式如下(以篮球投篮为例):
  Basketball Shoot
  这样就可以通过awk顺利提取附近的文本内容,具体实现如下:
  # split url_24
page_key='class="title"'
page_output='output_page.log'
page_output_url_start='https://play.google.com/store/apps/'
page_output_url='output_top800_url.log'
function page_split(){
grep $page_key $(ls $url_output* | sort -t "_" -k6 -n) > tmp_page_grepURL.log # use $url_output
awk -F'[]' '{for(i=1;i> $log
echo "================= $date ================" >> $log


# mysql database and table to create
HOST='localhost'
PORT='3306'
USER='root'
PWD='xxxxxx'
DBNAME='top800'
TABLENAME='gametop800'

mysql_login=''
mysql_create_db=''
mysql_create_table=''


function mysql_create(){
echo "login mysql $HOST:$PORT ..." >> $log
mysql_login="mysql -h $HOST -P $PORT -u $USER -p$PWD" # mysql -h host -P port -u root -p pwd
echo | ${mysql_login}
if [ $? -ne 0 ]; then
echo "login mysql ${HOST}:${PORT} failed.." >> $log
exit 1
else
echo "login mysql ${HOST}:${PORT} success!" >> $log
fi

echo "create database $DBNAME ..." >> $log
mysql_create_db="create database if not exists $DBNAME"
echo ${mysql_create_db} | ${mysql_login}
if [ $? -ne 0 ]; then
echo "create db ${DBNAME} failed.." >> $log
else
echo "create db ${DBNAME} success!" >> $log
fi

echo "create table $TABLENAME ..." >> $log
mysql_create_table="create table $TABLENAME(
id char(50) not null,
url char(255),
top int,
name char(100),
category char(50),
rating char(10),
ratingcount char(20),
download char(30),
price char(20),
publishdate char(20),
version char(40),
filesize char(40),
requireandroid char(40),
contentrating char(40),
country char(10) not null,
dtime date not null default \"2011-01-01\",
primary key(id, country, dtime)
)"

echo ${mysql_create_table} | ${mysql_login} ${DBNAME}
if [ $? -ne 0 ]; then
echo "create table ${TABLENAME} fail..." >> $log
else
echo "create table ${TABLENAME} success!" >> $log
fi
}
  脚本功能说明:
  首先登录mysql数据库,判断mysql服务器、端口号、用户名、密码是否正确。如果不正确,则登录失败退出(exit1);如果正确,则登录成功,继续下一步
  然后,创建数据库名,判断数据库是否存在,如果不存在,则创建;如果存在,继续下一步(注意:创建数据库时,需要验证是否登录数据库成功,否则无法操作)
  最后创建数据库表,首先设计数据库表的各个字段,然后创建数据库表,具体判断方法与创建数据库名称相同
  遍历游戏属性信息文本,全部插入mysql数据库统一存储管理
  # Author : yanggang
# Datetime : 2011.10.24 21:45:09
# ============================================================
#!/bin/sh


# insert mysql
file_input='output_top800_url_page'
file_output='sql_output'

HOST='localhost'
PORT='3306'
USER='root'
PWD='xxxxxx'
DBNAME='top800'
TABLENAME='gametop800'

col_id=''
col_url=''
col_top=1
col_name=''
col_category=''
col_rating=''
col_ratingcount=''
col_download=''
col_price=''
col_publishdate=''
col_version=''
col_filesize=''
col_requireandroid=''
col_contentrating=''
col_country=''
col_dtime=''

sql_insert='insert into gametop800 values("com.mobile.games", "url", 3, "minesweeping",
"games", "4.8", "89789", "1000000-5000000000", "free", "2011-2-30", "1.2.1", "1.5M", "1.5 up", "middle", "china", "2011-10-10")'

function mysql_insert(){
rm -rf $file_output
touch $file_output

DBNAME=$1
col_dtime=$2
col_country=$3
echo 'col_dtime========='$col_dtime

while read line
do
col_id=$(echo $line | cut -f 1 -d "%" | cut -f 1 -d "&" | cut -f 2 -d "=")
col_url=$(echo $line | cut -f 1 -d "%")
col_name=$(echo $line | cut -f 2 -d "%")
col_category=$(echo $line | cut -f 3 -d "%")
col_rating=$(echo $line | cut -f 4 -d "%")
col_ratingcount=$(echo $line | cut -f 5 -d "%")
col_download=$(echo $line | cut -f 6 -d "%")
col_price=$(echo $line | cut -f 7 -d "%")
col_publishdate=$(echo $line | cut -f 8 -d "%")
col_version=$(echo $line | cut -f 9 -d "%")
col_filesize=$(echo $line | cut -f 10 -d "%")
col_requireandroid=$(echo $line | cut -f 11 -d "%")
col_contentrating=$(echo $line | cut -f 12 -d "%")


sql_insert='insert into '$TABLENAME' values('"\"$col_id\", \"$col_url\", $col_top,
\"$col_name\", \"$col_category\", \"$col_rating\", \"$col_ratingcount\", \"$col_download\",
\"$col_price\", \"$col_publishdate\", \"$col_version\", \"$col_filesize\", \"$col_requireandroid\",
\"$col_contentrating\", \"$col_country\", \"$col_dtime\""');'

echo $sql_insert >> $file_output
mysql -h $HOST -P $PORT -u $USER -p$PWD -e "use $DBNAME; $sql_insert"

col_top=`expr $col_top + 1`
done < $file_input
}
  脚本功能说明:
  插入数据库脚本比较简单,主要实现两个功能:游戏排名号(col_top)和数据库语句插入($sql_insert)
  通过while read line循环,读取模块5提取的游戏属性信息文本文件,分割每一行得到对应的字段(cut -f 2 -d "%"),赋值给insert语句(sql_insert)
  最后通过mysql -h $HOST -P $PORT -u $USER-p$PWD -e "use $DBNAME; $sql_insert",登录mysql数据库,执行插入语句$sql_insert
  7、生成HTML报告
  shell 通过连接字符串 table + tr + td + info 来生成 html web 报告。详情请参考我之前的博客:shell将txt转换为html
  8、通过电子邮件发送报告
  邮件发送模块主要采用/usr/bin/mutt的方式。邮件正文显示html报告(默认为美国),其他国家以附件形式发送。详细请参考我之前的博客:linuxshell发送邮件附件
  使用 crontab 命令定期发送电子邮件。具体配置和使用可以参考我之前写的博客:linux定时运行命令script-crontab
  9、网页查询报告
  使用JSP提取MySQL中存储的游戏属性信息,循环生成游戏排名的网页信息,请参考我之前的博客:LinuxJSP连接MySQL数据库
  10、 排名趋势图
  趋势图,使用第三方JFreeChart图表生成工具,请参考我之前的博客:JFreeChart学习实例
  游戏排名趋势图生成后,需要嵌套到JSP网页中进行展示。完整的排名趋势图请参考我之前的博客:JFreeChart Project Example
  自动化主控制脚本
  12国游戏排名系统,免费ip代理过滤——“网络爬虫——”数据库保存——“生成排名报告——”及时发送邮件报告——“游戏排名查询——”趋势图生成
  都实现了整个流程的自动化,以下是各个模块的脚本实现和功能说明:
  
  通过配置服务器的crontab定时运行进程命令,在早上00:01:00(早上0:01:00),主控脚本top10_all.sh会自动启动。
  每天生成的日报使用主控脚本自动生成当天的文件夹,保存当天的抓包数据、分析数据、结果数据,如下图所示:
  
  注:以上文件夹数据为去年测试数据的副本,排名并非本人笔记本截图
  因为通过远程代理爬取12个国家排名前800的TOP800需要消耗网络资源、内存资源和时间,严重影响我的上网体验~~~~(&gt;_

curl 抓取网页(块传输编码(ChunkedTransfer)改变消息主体(图) )

网站优化优采云 发表了文章 • 0 个评论 • 65 次浏览 • 2021-09-22 07:06 • 来自相关话题

  curl 抓取网页(块传输编码(ChunkedTransfer)改变消息主体(图)
)
  块传输代码
  chunked编码更改消息正文使消息正文(消息正文,消息正文与实体身体不同,并且将引入以下章节)块传输。每个块都有自己的尺寸(大小)指示器,它立即成为所有块之后收录实体头的可选剪辑。这允许发送传输以动态生成内容,并且可以携带有用的信息,这允许收件人确定消息是否完整。
  4、 curl可以支持在指定要下载的链接时支持URL的序列或集合,并且WGET不能像这样。
  5、 wget支持递归下载,卷曲没有此功能。
  二、网站 crawling实例
  爬网页面,分为URL URL和代理代理。以百度主页为例。
  1、 url url方法爬网
  (1) curl下载百度归属页面内容,保存在百度_html文件中
  curl http://www.baidu.com/ -o baidu_html
  (2) wget下载百度家庭内容,保存在Baidu_html文件中
  wget http://www.baidu.com/ -O baidu_html
  有时,由于网络速度/数据包丢失/服务器停机/等等,有必要临时下载网页。此时,您可能需要多次发送连接,请求服务器响应;如果您仍然没有回复,则可以确认服务器存在问题。
  (1) curl多次尝试
  curl --retry 10 --retry-delay 60 --retry-max-time 60 http://www.baidu.com/ -o baidu_html
  注意:--retry表示重试次数; - 延迟指示两个重试之间的间隔(单位:秒); - 重试 - 最大时间意味着超时。
  curl -y 60 -Y 1 -m 60 http://www.baidu.com -o baidu_html
  注意:-y表示测试网络的时间; - 我表示停止传输速度的限制(单位:字节/秒); - m表示最大连接时间,超出连接自动断开连接以放弃连接
  (2) wget多次尝试
  wget -t 10 -w 60 -T 30 http://www.baidu.com/ -O baidu_html
  注意:-t(-tries)表示扭转数量; -w表示两次重试之间的时间间隔; - t表示链接超时。
  2、代理代理爬网
  代理代理下载,是间接通过连接中间服务器下载URL网页的过程,而不是URL直接连接网站 Server下载。这里的代理使用12 7.0.0. 1:8080来测试。
  (1) curl捕获百度家“
  curl -x 127.0.0.1:8080 -o baidu_html http://www.baidu.com
  注意:-x表示代理服务器(IP:端口),端口频率为80,8080,8086,8888,3128等,默认为80,即卷曲首先连接到代理服务器12 7.0.0. 1:8080,然后下载百度主页,最后12 7.@@@ @ 1:8080通过下载的百度家卷曲到本地
  (2) wget通过代理商抓住百度家
  通过代理下载,使用curl也不是,您需要设置http_proxy = IP:端口
  代理服务器的
  首先。
  以Ubuntu为例,在当前用户目录(CD〜)中,创建一个新的WGet配置文件(.wgetrc),输入代理配置:
  http_proxy=127.0.0.1:8080
  然后输入WGET CRAWLER命令:
  wget http://www.baidu.com -O baidu_html 查看全部

  curl 抓取网页(块传输编码(ChunkedTransfer)改变消息主体(图)
)
  块传输代码
  chunked编码更改消息正文使消息正文(消息正文,消息正文与实体身体不同,并且将引入以下章节)块传输。每个块都有自己的尺寸(大小)指示器,它立即成为所有块之后收录实体头的可选剪辑。这允许发送传输以动态生成内容,并且可以携带有用的信息,这允许收件人确定消息是否完整。
  4、 curl可以支持在指定要下载的链接时支持URL的序列或集合,并且WGET不能像这样。
  5、 wget支持递归下载,卷曲没有此功能。
  二、网站 crawling实例
  爬网页面,分为URL URL和代理代理。以百度主页为例。
  1、 url url方法爬网
  (1) curl下载百度归属页面内容,保存在百度_html文件中
  curl http://www.baidu.com/ -o baidu_html
  (2) wget下载百度家庭内容,保存在Baidu_html文件中
  wget http://www.baidu.com/ -O baidu_html
  有时,由于网络速度/数据包丢失/服务器停机/等等,有必要临时下载网页。此时,您可能需要多次发送连接,请求服务器响应;如果您仍然没有回复,则可以确认服务器存在问题。
  (1) curl多次尝试
  curl --retry 10 --retry-delay 60 --retry-max-time 60 http://www.baidu.com/ -o baidu_html
  注意:--retry表示重试次数; - 延迟指示两个重试之间的间隔(单位:秒); - 重试 - 最大时间意味着超时。
  curl -y 60 -Y 1 -m 60 http://www.baidu.com -o baidu_html
  注意:-y表示测试网络的时间; - 我表示停止传输速度的限制(单位:字节/秒); - m表示最大连接时间,超出连接自动断开连接以放弃连接
  (2) wget多次尝试
  wget -t 10 -w 60 -T 30 http://www.baidu.com/ -O baidu_html
  注意:-t(-tries)表示扭转数量; -w表示两次重试之间的时间间隔; - t表示链接超时。
  2、代理代理爬网
  代理代理下载,是间接通过连接中间服务器下载URL网页的过程,而不是URL直接连接网站 Server下载。这里的代理使用12 7.0.0. 1:8080来测试。
  (1) curl捕获百度家“
  curl -x 127.0.0.1:8080 -o baidu_html http://www.baidu.com
  注意:-x表示代理服务器(IP:端口),端口频率为80,8080,8086,8888,3128等,默认为80,即卷曲首先连接到代理服务器12 7.0.0. 1:8080,然后下载百度主页,最后12 7.@@@ @ 1:8080通过下载的百度家卷曲到本地
  (2) wget通过代理商抓住百度家
  通过代理下载,使用curl也不是,您需要设置http_proxy = IP:端口
  代理服务器的
  首先。
  以Ubuntu为例,在当前用户目录(CD〜)中,创建一个新的WGet配置文件(.wgetrc),输入代理配置:
  http_proxy=127.0.0.1:8080
  然后输入WGET CRAWLER命令:
  wget http://www.baidu.com -O baidu_html

curl 抓取网页(PHP利用CurlFunctions实现并发多线程下载文件(一) )

网站优化优采云 发表了文章 • 0 个评论 • 86 次浏览 • 2021-09-15 01:04 • 来自相关话题

  curl 抓取网页(PHP利用CurlFunctions实现并发多线程下载文件(一)
)
  本文文章主要介绍基于curl的PHP实现多线程爬取。有兴趣的可以参考一下,希望对大家有帮助。
  PHP可以使用Curl来完成各种文件传输操作,比如模拟浏览器发送GET、POST请求等,但是由于PHP语言本身不支持多线程,所以开发爬虫程序的效率不高,所以经常需要Curl。 Multi Functions 该函数实现多线程并发访问多个URL地址,实现多线程并发抓取网页或下载文件
  代码如下:
  再看几个例子
  (1)以下代码是抓取多个网址,然后将抓取到的网址的页面代码写入指定文件
  $urls = array(
&#39;http://www.jb51.net/&#39;,
&#39;http://www.google.com/&#39;,
&#39;http://www.example.com/&#39;
); // 设置要抓取的页面URL
$save_to=&#39;/test.txt&#39;; // 把抓取的代码写入该文件
$st = fopen($save_to,"a");
$mh = curl_multi_init();
foreach ($urls as $i => $url) {
$conn[$i] = curl_init($url);
curl_setopt($conn[$i], CURLOPT_USERAGENT, "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0)");
curl_setopt($conn[$i], CURLOPT_HEADER ,0);
curl_setopt($conn[$i], CURLOPT_CONNECTTIMEOUT,60);
curl_setopt($conn[$i], CURLOPT_FILE,$st); // 将爬取的代码写入文件
curl_multi_add_handle ($mh,$conn[$i]);
} // 初始化
do {
curl_multi_exec($mh,$active);
} while ($active); // 执行
foreach ($urls as $i => $url) {
curl_multi_remove_handle($mh,$conn[$i]);
curl_close($conn[$i]);
} // 结束清理
curl_multi_close($mh);
fclose($st);
  (2)下面的代码和上面的意思一样,只不过这个地方先把获取的代码放入变量中,然后将获取的内容写入指定的文件
  $urls = array(
&#39;http://www.jb51.net/&#39;,
&#39;http://www.google.com/&#39;,
&#39;http://www.example.com/&#39;
);
$save_to=&#39;/test.txt&#39;; // 把抓取的代码写入该文件
$st = fopen($save_to,"a");
$mh = curl_multi_init();
foreach ($urls as $i => $url) {
$conn[$i] = curl_init($url);
curl_setopt($conn[$i], CURLOPT_USERAGENT, "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0)");
curl_setopt($conn[$i], CURLOPT_HEADER ,0);
curl_setopt($conn[$i], CURLOPT_CONNECTTIMEOUT,60);
curl_setopt($conn[$i],CURLOPT_RETURNTRANSFER,true); // 不将爬取代码写到浏览器,而是转化为字符串
curl_multi_add_handle ($mh,$conn[$i]);
}
do {
curl_multi_exec($mh,$active);
} while ($active);
foreach ($urls as $i => $url) {
$data = curl_multi_getcontent($conn[$i]); // 获得爬取的代码字符串
fwrite($st,$data); // 将字符串写入文件
} // 获得数据变量,并写入文件
foreach ($urls as $i => $url) {
curl_multi_remove_handle($mh,$conn[$i]);
curl_close($conn[$i]);
}
curl_multi_close($mh);
fclose($st);
  (3)以下代码实现使用PHP的Curl Functions实现文件的并发多线程下载
  $urls=array(
&#39;http://www.jb51.net/5w.zip&#39;,
&#39;http://www.jb51.net/5w.zip&#39;,
&#39;http://www.jb51.net/5w.zip&#39;
);
$save_to=&#39;./home/&#39;;
$mh=curl_multi_init();
foreach($urls as $i=>$url){
$g=$save_to.basename($url);
if(!is_file($g)){
$conn[$i]=curl_init($url);
$fp[$i]=fopen($g,"w");
curl_setopt($conn[$i],CURLOPT_USERAGENT,"Mozilla/4.0(compatible; MSIE 7.0; Windows NT 6.0)");
curl_setopt($conn[$i],CURLOPT_FILE,$fp[$i]);
curl_setopt($conn[$i],CURLOPT_HEADER ,0);
curl_setopt($conn[$i],CURLOPT_CONNECTTIMEOUT,60);
curl_multi_add_handle($mh,$conn[$i]);
}
}
do{
$n=curl_multi_exec($mh,$active);
}while($active);
foreach($urls as $i=>$url){
curl_multi_remove_handle($mh,$conn[$i]);
curl_close($conn[$i]);
fclose($fp[$i]);
}
curl_multi_close($mh);$urls=array(
&#39;http://www.jb51.net/5w.zip&#39;,
&#39;http://www.jb51.net/5w.zip&#39;,
&#39;http://www.jb51.net/5w.zip&#39;
);
$save_to=&#39;./home/&#39;;
$mh=curl_multi_init();
foreach($urls as $i=>$url){
$g=$save_to.basename($url);
if(!is_file($g)){
$conn[$i]=curl_init($url);
$fp[$i]=fopen($g,"w");
curl_setopt($conn[$i],CURLOPT_USERAGENT,"Mozilla/4.0(compatible; MSIE 7.0; Windows NT 6.0)");
curl_setopt($conn[$i],CURLOPT_FILE,$fp[$i]);
curl_setopt($conn[$i],CURLOPT_HEADER ,0);
curl_setopt($conn[$i],CURLOPT_CONNECTTIMEOUT,60);
curl_multi_add_handle($mh,$conn[$i]);
}
}
do{
$n=curl_multi_exec($mh,$active);
}while($active);
foreach($urls as $i=>$url){
curl_multi_remove_handle($mh,$conn[$i]);
curl_close($conn[$i]);
fclose($fp[$i]);
}
curl_multi_close($mh); 查看全部

  curl 抓取网页(PHP利用CurlFunctions实现并发多线程下载文件(一)
)
  本文文章主要介绍基于curl的PHP实现多线程爬取。有兴趣的可以参考一下,希望对大家有帮助。
  PHP可以使用Curl来完成各种文件传输操作,比如模拟浏览器发送GET、POST请求等,但是由于PHP语言本身不支持多线程,所以开发爬虫程序的效率不高,所以经常需要Curl。 Multi Functions 该函数实现多线程并发访问多个URL地址,实现多线程并发抓取网页或下载文件
  代码如下:
  再看几个例子
  (1)以下代码是抓取多个网址,然后将抓取到的网址的页面代码写入指定文件
  $urls = array(
&#39;http://www.jb51.net/&#39;,
&#39;http://www.google.com/&#39;,
&#39;http://www.example.com/&#39;
); // 设置要抓取的页面URL
$save_to=&#39;/test.txt&#39;; // 把抓取的代码写入该文件
$st = fopen($save_to,"a");
$mh = curl_multi_init();
foreach ($urls as $i => $url) {
$conn[$i] = curl_init($url);
curl_setopt($conn[$i], CURLOPT_USERAGENT, "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0)");
curl_setopt($conn[$i], CURLOPT_HEADER ,0);
curl_setopt($conn[$i], CURLOPT_CONNECTTIMEOUT,60);
curl_setopt($conn[$i], CURLOPT_FILE,$st); // 将爬取的代码写入文件
curl_multi_add_handle ($mh,$conn[$i]);
} // 初始化
do {
curl_multi_exec($mh,$active);
} while ($active); // 执行
foreach ($urls as $i => $url) {
curl_multi_remove_handle($mh,$conn[$i]);
curl_close($conn[$i]);
} // 结束清理
curl_multi_close($mh);
fclose($st);
  (2)下面的代码和上面的意思一样,只不过这个地方先把获取的代码放入变量中,然后将获取的内容写入指定的文件
  $urls = array(
&#39;http://www.jb51.net/&#39;,
&#39;http://www.google.com/&#39;,
&#39;http://www.example.com/&#39;
);
$save_to=&#39;/test.txt&#39;; // 把抓取的代码写入该文件
$st = fopen($save_to,"a");
$mh = curl_multi_init();
foreach ($urls as $i => $url) {
$conn[$i] = curl_init($url);
curl_setopt($conn[$i], CURLOPT_USERAGENT, "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0)");
curl_setopt($conn[$i], CURLOPT_HEADER ,0);
curl_setopt($conn[$i], CURLOPT_CONNECTTIMEOUT,60);
curl_setopt($conn[$i],CURLOPT_RETURNTRANSFER,true); // 不将爬取代码写到浏览器,而是转化为字符串
curl_multi_add_handle ($mh,$conn[$i]);
}
do {
curl_multi_exec($mh,$active);
} while ($active);
foreach ($urls as $i => $url) {
$data = curl_multi_getcontent($conn[$i]); // 获得爬取的代码字符串
fwrite($st,$data); // 将字符串写入文件
} // 获得数据变量,并写入文件
foreach ($urls as $i => $url) {
curl_multi_remove_handle($mh,$conn[$i]);
curl_close($conn[$i]);
}
curl_multi_close($mh);
fclose($st);
  (3)以下代码实现使用PHP的Curl Functions实现文件的并发多线程下载
  $urls=array(
&#39;http://www.jb51.net/5w.zip&#39;,
&#39;http://www.jb51.net/5w.zip&#39;,
&#39;http://www.jb51.net/5w.zip&#39;
);
$save_to=&#39;./home/&#39;;
$mh=curl_multi_init();
foreach($urls as $i=>$url){
$g=$save_to.basename($url);
if(!is_file($g)){
$conn[$i]=curl_init($url);
$fp[$i]=fopen($g,"w");
curl_setopt($conn[$i],CURLOPT_USERAGENT,"Mozilla/4.0(compatible; MSIE 7.0; Windows NT 6.0)");
curl_setopt($conn[$i],CURLOPT_FILE,$fp[$i]);
curl_setopt($conn[$i],CURLOPT_HEADER ,0);
curl_setopt($conn[$i],CURLOPT_CONNECTTIMEOUT,60);
curl_multi_add_handle($mh,$conn[$i]);
}
}
do{
$n=curl_multi_exec($mh,$active);
}while($active);
foreach($urls as $i=>$url){
curl_multi_remove_handle($mh,$conn[$i]);
curl_close($conn[$i]);
fclose($fp[$i]);
}
curl_multi_close($mh);$urls=array(
&#39;http://www.jb51.net/5w.zip&#39;,
&#39;http://www.jb51.net/5w.zip&#39;,
&#39;http://www.jb51.net/5w.zip&#39;
);
$save_to=&#39;./home/&#39;;
$mh=curl_multi_init();
foreach($urls as $i=>$url){
$g=$save_to.basename($url);
if(!is_file($g)){
$conn[$i]=curl_init($url);
$fp[$i]=fopen($g,"w");
curl_setopt($conn[$i],CURLOPT_USERAGENT,"Mozilla/4.0(compatible; MSIE 7.0; Windows NT 6.0)");
curl_setopt($conn[$i],CURLOPT_FILE,$fp[$i]);
curl_setopt($conn[$i],CURLOPT_HEADER ,0);
curl_setopt($conn[$i],CURLOPT_CONNECTTIMEOUT,60);
curl_multi_add_handle($mh,$conn[$i]);
}
}
do{
$n=curl_multi_exec($mh,$active);
}while($active);
foreach($urls as $i=>$url){
curl_multi_remove_handle($mh,$conn[$i]);
curl_close($conn[$i]);
fclose($fp[$i]);
}
curl_multi_close($mh);

curl 抓取网页(curl抓取网页的执行命令-|curl--)

网站优化优采云 发表了文章 • 0 个评论 • 82 次浏览 • 2021-09-13 03:01 • 来自相关话题

  curl 抓取网页(curl抓取网页的执行命令-|curl--)
  curl抓取网页
  1、执行命令:|bash-
  2、执行命令:||bash-
  4、服务管理中的curl命令:curl-a/some/documents/test/config/config.xml/some/documents/test/config.xml
  6、scheme环境:选择当前用户下的前100个scheme,
  7、curl的网址判断:echo123"http"一开始会报错,但是只要你把服务器的443端口号改为80,就可以输入123如果你没有改123端口号,那就是表示百度的网址,下次换一个试试例如:curl-e"123。160。99。136"|bash因为是从远程连接的,所以不会出错,但是如果远程没有改为123,或者改了443端口号还是没有输入www是以域名来访问网页curl的命令输入窗口的按键是fn命令fn功能请自行脑补。
  个人一般在windows环境下写脚本,用msf打开shell文件不好,更别说shell中还要加上编辑功能。
  登录的话就抓shellcode用爬虫,
  cmd命令行就可以, 查看全部

  curl 抓取网页(curl抓取网页的执行命令-|curl--)
  curl抓取网页
  1、执行命令:|bash-
  2、执行命令:||bash-
  4、服务管理中的curl命令:curl-a/some/documents/test/config/config.xml/some/documents/test/config.xml
  6、scheme环境:选择当前用户下的前100个scheme,
  7、curl的网址判断:echo123"http"一开始会报错,但是只要你把服务器的443端口号改为80,就可以输入123如果你没有改123端口号,那就是表示百度的网址,下次换一个试试例如:curl-e"123。160。99。136"|bash因为是从远程连接的,所以不会出错,但是如果远程没有改为123,或者改了443端口号还是没有输入www是以域名来访问网页curl的命令输入窗口的按键是fn命令fn功能请自行脑补。
  个人一般在windows环境下写脚本,用msf打开shell文件不好,更别说shell中还要加上编辑功能。
  登录的话就抓shellcode用爬虫,
  cmd命令行就可以,

curl 抓取网页(抓取网页内容,PHP手册真乃圣经也也乃也))

网站优化优采云 发表了文章 • 0 个评论 • 76 次浏览 • 2021-09-09 19:24 • 来自相关话题

  curl 抓取网页(抓取网页内容,PHP手册真乃圣经也也乃也))
  获取网页内容,PHP有几个可以实现的内置函数,比如file()、file_get_contents()等,都支持URL参数。但要实现更复杂的操作,这些功能就无能为力了。
  cURL 是一个文件传输工具,它使用 URL 语法在命令行下工作。 cURL 提供了一个 PHP 扩展。有了这个扩展,你可以完全模拟浏览器操作,就像使用浏览器浏览网页一样。可以设置header内容、设置cookie数据、POST数据、上传文件、设置代理等,其实我们这里讨论的爬取网页内容只是其常用的应用之一。
  cURL 官方网站:
  PHP cURL 扩展:
  在Windows下添加这个扩展很简单,加载php_curl.dll即可。去掉php.ini文件extension=php_curl.dll前面的分号,将php_curl.dll复制到PHP扩展目录下或者重启C:\Windows\system32目录下的Web服务器。 php_curl.dll 在 PHP 的 ZIP 包中提供。
  Linux下,需要先安装cURL。一种方法是编译成PHP,编译配置时加上--with-curl[=DIR]。另一种方法是编译成PHP模块加载,编译cURL模块的方法和编译其他PHP模块的方法是一样的。以下是基本命令:
  cd /path/to/php/source 进入PHP源代码目录
  cd ext/curl 进入cURL模块源码目录
  /usr/local/php/bin/phpize 生成编译配置文件
  ./configure --with-php-config=/usr/local/php/bin/php-config
  制作
  进行安装
  编译完成生成curl.so,修改php.ini,加载模块:
  extension="/path/to/extension/curl.so"
  测试cURL扩展是否加载,新建PHP文件:
  抓取网页示例:
  curl_setopt() 可以设置很多选项。更多选项请参考PHP手册。
  更多的功能和用法请参考PHP手册(再次废话,强调PHP手册真的是一本圣经)。
  2010-12-06 更新
  ============
  当前,移动互联网发展迅猛。很多门户网站都开发了手机网站,比如腾讯()、新浪()、网易()、搜狐(),一般的手机网站都会对浏览器的User Agent进行检测做出相应的适应。但是用户代理不是很可靠,因为它是从客户端发送到服务器的。我们可以通过各种方式伪造用户代理。 Firefox 有一个插件 User Agent Switcher()(这个主页在中国可能无法访问。翻墙)就是这样一个工具。当然,本文讨论的cURL也可以做到这一点。在开发过程中,我们可能需要伪造用户代理。以下是几款主流平台智能手机自带浏览器的User Agent。
  诺基亚 E71(S60 第三版):
  Mozilla/5.0 (SymbianOS/9.2; U; Series60/3.1 NokiaE71/1.00.000; Profile/MIDP-2.0 Configuration/CLDC-1.1;) AppleWebKit/413(KHTML,如 Gecko)Safari/413
  HTC Desire (安卓2.1/2.2):
  Mozilla/5.0 (Linux; U; Android 2.1-update1; zh-cn; Desire_A8181 Build/ERE27) AppleWebKit/530.17 (KHTML, like Gecko) 版本/4.0 移动版 Safari/530.17
  iPhone 3GS(iOS 3):
  Mozilla/5.0 (iPhone; U; CPU iPhone OS 3_0 like Mac OS X; zh-cn) AppleWebKit/420.1 (KHTML, like Gecko) 版本/3.0 Mobile/1A542a Safari /419.3
  黑莓 8700(黑莓):
  BlackBerry8700/4.1.0 Profile/MIDP-2.0 Configuration/CLDC-1.1 VendorID/100 查看全部

  curl 抓取网页(抓取网页内容,PHP手册真乃圣经也也乃也))
  获取网页内容,PHP有几个可以实现的内置函数,比如file()、file_get_contents()等,都支持URL参数。但要实现更复杂的操作,这些功能就无能为力了。
  cURL 是一个文件传输工具,它使用 URL 语法在命令行下工作。 cURL 提供了一个 PHP 扩展。有了这个扩展,你可以完全模拟浏览器操作,就像使用浏览器浏览网页一样。可以设置header内容、设置cookie数据、POST数据、上传文件、设置代理等,其实我们这里讨论的爬取网页内容只是其常用的应用之一。
  cURL 官方网站:
  PHP cURL 扩展:
  在Windows下添加这个扩展很简单,加载php_curl.dll即可。去掉php.ini文件extension=php_curl.dll前面的分号,将php_curl.dll复制到PHP扩展目录下或者重启C:\Windows\system32目录下的Web服务器。 php_curl.dll 在 PHP 的 ZIP 包中提供。
  Linux下,需要先安装cURL。一种方法是编译成PHP,编译配置时加上--with-curl[=DIR]。另一种方法是编译成PHP模块加载,编译cURL模块的方法和编译其他PHP模块的方法是一样的。以下是基本命令:
  cd /path/to/php/source 进入PHP源代码目录
  cd ext/curl 进入cURL模块源码目录
  /usr/local/php/bin/phpize 生成编译配置文件
  ./configure --with-php-config=/usr/local/php/bin/php-config
  制作
  进行安装
  编译完成生成curl.so,修改php.ini,加载模块:
  extension="/path/to/extension/curl.so"
  测试cURL扩展是否加载,新建PHP文件:
  抓取网页示例:
  curl_setopt() 可以设置很多选项。更多选项请参考PHP手册。
  更多的功能和用法请参考PHP手册(再次废话,强调PHP手册真的是一本圣经)。
  2010-12-06 更新
  ============
  当前,移动互联网发展迅猛。很多门户网站都开发了手机网站,比如腾讯()、新浪()、网易()、搜狐(),一般的手机网站都会对浏览器的User Agent进行检测做出相应的适应。但是用户代理不是很可靠,因为它是从客户端发送到服务器的。我们可以通过各种方式伪造用户代理。 Firefox 有一个插件 User Agent Switcher()(这个主页在中国可能无法访问。翻墙)就是这样一个工具。当然,本文讨论的cURL也可以做到这一点。在开发过程中,我们可能需要伪造用户代理。以下是几款主流平台智能手机自带浏览器的User Agent。
  诺基亚 E71(S60 第三版):
  Mozilla/5.0 (SymbianOS/9.2; U; Series60/3.1 NokiaE71/1.00.000; Profile/MIDP-2.0 Configuration/CLDC-1.1;) AppleWebKit/413(KHTML,如 Gecko)Safari/413
  HTC Desire (安卓2.1/2.2):
  Mozilla/5.0 (Linux; U; Android 2.1-update1; zh-cn; Desire_A8181 Build/ERE27) AppleWebKit/530.17 (KHTML, like Gecko) 版本/4.0 移动版 Safari/530.17
  iPhone 3GS(iOS 3):
  Mozilla/5.0 (iPhone; U; CPU iPhone OS 3_0 like Mac OS X; zh-cn) AppleWebKit/420.1 (KHTML, like Gecko) 版本/3.0 Mobile/1A542a Safari /419.3
  黑莓 8700(黑莓):
  BlackBerry8700/4.1.0 Profile/MIDP-2.0 Configuration/CLDC-1.1 VendorID/100

curl 抓取网页(PHP的调用测试(get(get)函数(图) )

网站优化优采云 发表了文章 • 0 个评论 • 101 次浏览 • 2021-09-09 08:10 • 来自相关话题

  curl 抓取网页(PHP的调用测试(get(get)函数(图)
)
  PHP 的 curl 功能真的很强大。里面有个curl_multi_init函数,就是批处理任务。可以用它来实现多进程同时抓取多条记录,优化常见的网页抓取程序。
  一个简单的获取函数:
  function http_get_multi($urls){
$count = count($urls);
$data = [];
$chs = [];
// 创建批处理cURL句柄
$mh = curl_multi_init();
// 创建cURL资源
for($i = 0; $i < $count; $i ++){
$chs[ $i ] = curl_init();
// 设置URL和相应的选项
curl_setopt($chs[ $i ], CURLOPT_RETURNTRANSFER, 1); // return don‘t print
curl_setopt($chs[ $i ], CURLOPT_URL, $urls[$i]);
curl_setopt($chs[ $i ], CURLOPT_HEADER, 0);
curl_multi_add_handle($mh, $chs[ $i ]);
}
// 增加句柄
// for($i = 0; $i < $count; $i ++){
// curl_multi_add_handle($mh, $chs[ $i ]);
// }
// 执行批处理句柄
do {
$mrc = curl_multi_exec($mh, $active);
} while ($active > 0);
while ($active and $mrc == CURLM_OK) {
if (curl_multi_select($mh) != -1) {
do {
$mrc = curl_multi_exec($mh, $active);
} while ($mrc == CURLM_CALL_MULTI_PERFORM);
}
}
for($i = 0; $i < $count; $i ++){
$content = curl_multi_getcontent($chs[ $i ]);
$data[ $i ] = ( curl_errno($chs[ $i ]) == 0 ) ? $content : false;
}
// 关闭全部句柄
for($i = 0; $i < $count; $i ++){
curl_multi_remove_handle($mh, $chs[ $i ]);
}
curl_multi_close($mh);
return $data;
}
  下面的调用测试(get() 函数就像这里:):
  //弄很多个网页的url<br />$url = [
‘http://www.baidu.com‘,
‘http://www.163.com‘,
‘http://www.sina.com.cn‘,
‘http://www.qq.com‘,
‘http://www.sohu.com‘,
‘http://www.douban.com‘,
‘http://www.cnblogs.com‘,
‘http://www.taobao.com‘,
‘http://www.php.net‘,
];
$urls = [];
for($i = 0; $i < 10; $i ++){
foreach($url as $r)
$urls[] = $r . ‘/?v=‘ . rand();
} <br /><br />//并发请求
$datas = http_get_multi($urls);
foreach($datas as $key => $data){
file_put_contents(‘log/multi_‘ . $key . ‘.txt‘, $data); // 记录一下请求结果。记得创建一个log文件夹
}
$t2 = microtime(true);
echo $t2 - $t1;
echo ‘<br />‘;<br /><br />//同步请求, get()函数如这里: http://www.cnblogs.com/whatmiss/p/7114954.html
$t1 = microtime(true);
foreach($urls as $key => $url){
file_put_contents(‘log/get_‘ . $key . ‘.txt‘, get($url)); // 记录一下请求结果。记得创建一个log文件夹
}
$t2 = microtime(true);
echo $t2 - $t1;
  测试结果显示出明显的差距,随着数据量的增加,差距会呈指数级扩大:
  2.4481401443481
21.68923997879
8.925509929657
24.73141503334
3.243185043335
23.384337902069
3.2841880321503
24.754415035248

3.2091829776764
29.068662881851 查看全部

  curl 抓取网页(PHP的调用测试(get(get)函数(图)
)
  PHP 的 curl 功能真的很强大。里面有个curl_multi_init函数,就是批处理任务。可以用它来实现多进程同时抓取多条记录,优化常见的网页抓取程序。
  一个简单的获取函数:
  function http_get_multi($urls){
$count = count($urls);
$data = [];
$chs = [];
// 创建批处理cURL句柄
$mh = curl_multi_init();
// 创建cURL资源
for($i = 0; $i < $count; $i ++){
$chs[ $i ] = curl_init();
// 设置URL和相应的选项
curl_setopt($chs[ $i ], CURLOPT_RETURNTRANSFER, 1); // return don‘t print
curl_setopt($chs[ $i ], CURLOPT_URL, $urls[$i]);
curl_setopt($chs[ $i ], CURLOPT_HEADER, 0);
curl_multi_add_handle($mh, $chs[ $i ]);
}
// 增加句柄
// for($i = 0; $i < $count; $i ++){
// curl_multi_add_handle($mh, $chs[ $i ]);
// }
// 执行批处理句柄
do {
$mrc = curl_multi_exec($mh, $active);
} while ($active > 0);
while ($active and $mrc == CURLM_OK) {
if (curl_multi_select($mh) != -1) {
do {
$mrc = curl_multi_exec($mh, $active);
} while ($mrc == CURLM_CALL_MULTI_PERFORM);
}
}
for($i = 0; $i < $count; $i ++){
$content = curl_multi_getcontent($chs[ $i ]);
$data[ $i ] = ( curl_errno($chs[ $i ]) == 0 ) ? $content : false;
}
// 关闭全部句柄
for($i = 0; $i < $count; $i ++){
curl_multi_remove_handle($mh, $chs[ $i ]);
}
curl_multi_close($mh);
return $data;
}
  下面的调用测试(get() 函数就像这里:):
  //弄很多个网页的url<br />$url = [
http://www.baidu.com‘,
http://www.163.com‘,
http://www.sina.com.cn‘,
http://www.qq.com‘,
http://www.sohu.com‘,
http://www.douban.com‘,
http://www.cnblogs.com‘,
http://www.taobao.com‘,
http://www.php.net‘,
];
$urls = [];
for($i = 0; $i < 10; $i ++){
foreach($url as $r)
$urls[] = $r . ‘/?v=‘ . rand();
} <br /><br />//并发请求
$datas = http_get_multi($urls);
foreach($datas as $key => $data){
file_put_contents(‘log/multi_‘ . $key . ‘.txt‘, $data); // 记录一下请求结果。记得创建一个log文件夹
}
$t2 = microtime(true);
echo $t2 - $t1;
echo ‘<br />‘;<br /><br />//同步请求, get()函数如这里: http://www.cnblogs.com/whatmiss/p/7114954.html
$t1 = microtime(true);
foreach($urls as $key => $url){
file_put_contents(‘log/get_‘ . $key . ‘.txt‘, get($url)); // 记录一下请求结果。记得创建一个log文件夹
}
$t2 = microtime(true);
echo $t2 - $t1;
  测试结果显示出明显的差距,随着数据量的增加,差距会呈指数级扩大:
  2.4481401443481
21.68923997879
8.925509929657
24.73141503334
3.243185043335
23.384337902069
3.2841880321503
24.754415035248

3.2091829776764
29.068662881851

curl 抓取网页(我另外一个博客中有一个 )

网站优化优采云 发表了文章 • 0 个评论 • 65 次浏览 • 2021-10-02 00:19 • 来自相关话题

  curl 抓取网页(我另外一个博客中有一个
)
  有一个我自己写的源代码,用于在另一个博客中抓取其他网页。之前调试的时候没有问题,发布后一段时间内容也没有问题,但是突然发现爬虫功能不行了。右键查看源文件,看到获取的数据是空的。
  我查看了我的源代码并在服务器上调试了几次。我什至重新抓包,查看了对方的网站数据。
  一开始以为是我服务器的IP被对方的服务器屏蔽了,于是把源码发给另一个朋友调试,发现不是这个原因。
  然后我怀疑对方是不是更新了算法,加密了程序,但是我在源码中对获取数据的模块变量做了echo输出,然后才发现获取的数据是乱码。
  
  第一眼看到乱码,还以为是对方的开发者加密了数据,于是放弃了几天。
  今天在源码中尝试对获取到的数据进行字符集转换,但是不管怎么转换,都是乱码。
  找了一天,终于在C#程序员里面写了一个idea。
  原来问题出在我的帖子的标题数据中。我在源代码中添加了一行'Accept-Encoding:gzip, deflate, br'。删除后问题解决,因为是gzip压缩导致的乱码。
  $cars = $GLOBALS['ua'];
$header = array(
"POST {$ii} HTTP/2.0",
"Host: {$web} ",
"filename: {$id} ",
"Referer: {$ii} ",
"Content-Type: text/html",
'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,video/webm,video/ogg,video/*;q=0.9,application/ogg;q=0.7,audio/*;q=0.6,*/*;q=0.5,application/signed-exchange;v=b3',
'Accept-Encoding:gzip, deflate, br',
'Accept-Language:zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2',
'Connection:keep-alive',
"Cookie: {$cars[1]}",
"User-Agent: {$cars[0]}",
"X-FORWARDED-FOR:180.149.134.142",
"CLIENT-IP:180.149.134.142",
);
echo "header: {$header[0]}
{$header[1]}
{$header[2]}
{$header[3]}
{$header[4]}
{$header[5]}
{$header[6]}
{$header[7]}
{$header[8]}
{$header[9]}
{$header[10]}
{$header[11]}
{$header[12]}
{$header[13]}
";
return $header;
  通过删除以下行来解决问题。
  'Accept-Encoding:gzip, deflate, br',
   查看全部

  curl 抓取网页(我另外一个博客中有一个
)
  有一个我自己写的源代码,用于在另一个博客中抓取其他网页。之前调试的时候没有问题,发布后一段时间内容也没有问题,但是突然发现爬虫功能不行了。右键查看源文件,看到获取的数据是空的。
  我查看了我的源代码并在服务器上调试了几次。我什至重新抓包,查看了对方的网站数据。
  一开始以为是我服务器的IP被对方的服务器屏蔽了,于是把源码发给另一个朋友调试,发现不是这个原因。
  然后我怀疑对方是不是更新了算法,加密了程序,但是我在源码中对获取数据的模块变量做了echo输出,然后才发现获取的数据是乱码。
  http://www.myzhenai.com.cn/wp- ... 4.png 300w, http://www.myzhenai.com.cn/wp- ... 8.png 768w, http://www.myzhenai.com.cn/wp- ... 6.png 1536w, http://www.myzhenai.com.cn/wp- ... a.png 1907w" />
  第一眼看到乱码,还以为是对方的开发者加密了数据,于是放弃了几天。
  今天在源码中尝试对获取到的数据进行字符集转换,但是不管怎么转换,都是乱码。
  找了一天,终于在C#程序员里面写了一个idea。
  原来问题出在我的帖子的标题数据中。我在源代码中添加了一行'Accept-Encoding:gzip, deflate, br'。删除后问题解决,因为是gzip压缩导致的乱码。
  $cars = $GLOBALS['ua'];
$header = array(
"POST {$ii} HTTP/2.0",
"Host: {$web} ",
"filename: {$id} ",
"Referer: {$ii} ",
"Content-Type: text/html",
'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,video/webm,video/ogg,video/*;q=0.9,application/ogg;q=0.7,audio/*;q=0.6,*/*;q=0.5,application/signed-exchange;v=b3',
'Accept-Encoding:gzip, deflate, br',
'Accept-Language:zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2',
'Connection:keep-alive',
"Cookie: {$cars[1]}",
"User-Agent: {$cars[0]}",
"X-FORWARDED-FOR:180.149.134.142",
"CLIENT-IP:180.149.134.142",
);
echo "header: {$header[0]}
{$header[1]}
{$header[2]}
{$header[3]}
{$header[4]}
{$header[5]}
{$header[6]}
{$header[7]}
{$header[8]}
{$header[9]}
{$header[10]}
{$header[11]}
{$header[12]}
{$header[13]}
";
return $header;
  通过删除以下行来解决问题。
  'Accept-Encoding:gzip, deflate, br',
  http://www.myzhenai.com.cn/wp- ... 3.png 300w, http://www.myzhenai.com.cn/wp- ... 8.png 768w, http://www.myzhenai.com.cn/wp- ... 6.png 1536w, http://www.myzhenai.com.cn/wp- ... 1.png 1887w" />

curl 抓取网页(使用PHP的cURL库可以简单和有效地去抓网页。)

网站优化优采云 发表了文章 • 0 个评论 • 99 次浏览 • 2021-09-28 21:06 • 来自相关话题

  curl 抓取网页(使用PHP的cURL库可以简单和有效地去抓网页。)
  使用 PHP 的 cURL 库来简单有效地抓取网页。你只需要运行一个脚本,然后分析你抓取的网页,然后你就可以通过编程的方式得到你想要的数据。无论您是想从链接中获取部分数据,还是获取 XML 文件并将其导入数据库,即使只是获取网页内容,cURL 都是一个强大的 PHP 库。本文主要介绍如何使用这个PHP库。
  启用卷曲设置
  首先我们要先判断我们的PHP是否启用了这个库,可以通过php_info()函数来获取这个信息。
  ﹤?php
phpinfo();
?﹥
  如果在网页上可以看到如下输出,说明cURL库已经开启。
  如果你看到它,那么你需要设置你的 PHP 并启用这个库。如果你是windows平台,很简单,你需要改变你的php.ini文件的设置,找到php_curl.dll,去掉前面的分号。如下:
  //取消下在的注释
extension=php_curl.dll
  如果你在 Linux 下,那么你需要重新编译你的 PHP。编辑时需要开启编译参数——在configure命令中添加“--with-curl”参数。
  一个小例子
  如果一切就绪,这里有一个小程序:
  ﹤?php
  // 初始化一个 cURL 对象
  $curl = curl_init();
  // 设置你需要爬取的网址
  curl_setopt($curl, CURLOPT_URL,'');
  // 设置标题
  curl_setopt($curl, CURLOPT_HEADER, 1);
  // 设置cURL参数,询问结果是保存在字符串中还是输出到屏幕上。
  curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
  // 运行 cURL 并请求一个网页
  $data = curl_exec($curl);
  // 关闭 URL 请求
  curl_close($curl);
  // 显示获取的数据
  var_dump($data);
  如何发布数据
  上面是抓取网页的代码,下面是到某个网页的POST数据。假设我们有一个处理表单的URL,可以接受两个表单域,一个是电话号码,一个是短信内容。
  ﹤?php
$phoneNumber = '13912345678';
$message = 'This message was generated by curl and php';
$curlPost = 'pNUMBER=' . urlencode($phoneNumber) . '&MESSAGE=' . urlencode($message) . '&SUBMIT=Send';
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'http://www.example.com/sendSMS.php');
curl_setopt($ch, CURLOPT_HEADER, 1);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $curlPost);
$data = curl_exec();
curl_close($ch);
?﹥
  从上面的程序可以看出,CURLOPT_POST是用来设置HTTP协议的POST方法而不是GET方法的,然后CURLOPT_POSTFIELDS是用来设置POST数据的。
  关于代理服务器
  以下是如何使用代理服务器的示例。请注意高亮的代码,代码很简单,我就不多说了。
  ﹤?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'http://www.example.com');
curl_setopt($ch, CURLOPT_HEADER, 1);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_HTTPPROXYTUNNEL, 1);
curl_setopt($ch, CURLOPT_PROXY, 'fakeproxy.com:1080');
curl_setopt($ch, CURLOPT_PROXYUSERPWD, 'user:password');
$data = curl_exec();
curl_close($ch);
?﹥
  关于 SSL 和 Cookie 查看全部

  curl 抓取网页(使用PHP的cURL库可以简单和有效地去抓网页。)
  使用 PHP 的 cURL 库来简单有效地抓取网页。你只需要运行一个脚本,然后分析你抓取的网页,然后你就可以通过编程的方式得到你想要的数据。无论您是想从链接中获取部分数据,还是获取 XML 文件并将其导入数据库,即使只是获取网页内容,cURL 都是一个强大的 PHP 库。本文主要介绍如何使用这个PHP库。
  启用卷曲设置
  首先我们要先判断我们的PHP是否启用了这个库,可以通过php_info()函数来获取这个信息。
  ﹤?php
phpinfo();
?﹥
  如果在网页上可以看到如下输出,说明cURL库已经开启。
  如果你看到它,那么你需要设置你的 PHP 并启用这个库。如果你是windows平台,很简单,你需要改变你的php.ini文件的设置,找到php_curl.dll,去掉前面的分号。如下:
  //取消下在的注释
extension=php_curl.dll
  如果你在 Linux 下,那么你需要重新编译你的 PHP。编辑时需要开启编译参数——在configure命令中添加“--with-curl”参数。
  一个小例子
  如果一切就绪,这里有一个小程序:
  ﹤?php
  // 初始化一个 cURL 对象
  $curl = curl_init();
  // 设置你需要爬取的网址
  curl_setopt($curl, CURLOPT_URL,'');
  // 设置标题
  curl_setopt($curl, CURLOPT_HEADER, 1);
  // 设置cURL参数,询问结果是保存在字符串中还是输出到屏幕上。
  curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
  // 运行 cURL 并请求一个网页
  $data = curl_exec($curl);
  // 关闭 URL 请求
  curl_close($curl);
  // 显示获取的数据
  var_dump($data);
  如何发布数据
  上面是抓取网页的代码,下面是到某个网页的POST数据。假设我们有一个处理表单的URL,可以接受两个表单域,一个是电话号码,一个是短信内容。
  ﹤?php
$phoneNumber = '13912345678';
$message = 'This message was generated by curl and php';
$curlPost = 'pNUMBER=' . urlencode($phoneNumber) . '&MESSAGE=' . urlencode($message) . '&SUBMIT=Send';
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'http://www.example.com/sendSMS.php');
curl_setopt($ch, CURLOPT_HEADER, 1);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $curlPost);
$data = curl_exec();
curl_close($ch);
?﹥
  从上面的程序可以看出,CURLOPT_POST是用来设置HTTP协议的POST方法而不是GET方法的,然后CURLOPT_POSTFIELDS是用来设置POST数据的。
  关于代理服务器
  以下是如何使用代理服务器的示例。请注意高亮的代码,代码很简单,我就不多说了。
  ﹤?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'http://www.example.com');
curl_setopt($ch, CURLOPT_HEADER, 1);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_HTTPPROXYTUNNEL, 1);
curl_setopt($ch, CURLOPT_PROXY, 'fakeproxy.com:1080');
curl_setopt($ch, CURLOPT_PROXYUSERPWD, 'user:password');
$data = curl_exec();
curl_close($ch);
?﹥
  关于 SSL 和 Cookie

curl 抓取网页( 其它命令参数用法,同url网址方式,和wget用法)

网站优化优采云 发表了文章 • 0 个评论 • 57 次浏览 • 2021-09-27 07:21 • 来自相关话题

  curl 抓取网页(
其它命令参数用法,同url网址方式,和wget用法)
  
  其他命令参数的用法与url方法相同,这里不再赘述。
  更多curl和wget的用法如ftp协议、迭代子目录等,可以查看man中的帮助手册
  知识拓展:
  在国内,由于某些原因,一般很难直接访问一些敏感的海外网站,需要通过VPN或代理服务器访问。
  如果校园网和教育网有IPv6,可以通过免费代理访问facebook、twitter、六维空间等网站
  其实除了VPN和IPv6+代理方式,普通用户还有其他方式访问国外网站
  这里有两个著名的自由球员网站:
  (全球数十个国家的自由代理,每日更新)
  (通过设置端口类型、代理类型、国家名称过滤)
  curl 项目示例
  使用curl+free agent实现全球12个国家googleplay游戏排名的网页抓取和趋势图查询(抓取网页模块全部用Shell编写,核心代码1000行左右)
  爬取google play游戏排名网页,首先需要分析网页的特点和规律:
  1、Google play游戏排名页面是“总分”格式,即一个页面URL显示了几个排名(比如24),这样的页面有几个构成了所有游戏的总排名
  2、 在每个页面的URL中,点击每个单独的游戏链接可以查看游戏的属性信息(如评分星级、发布日期、版本号、SDK版本号、游戏类别、下载量等)
  需要解决的问题:
  1、如何抓取所有游戏的总排名?
  2、抓取整体排名后,如何拼接网址抓取各个单独的游戏页面?
  3、获取各个单独的游戏网页后,如何提取网页中游戏的属性信息(即评分星级、发布日期...)?
  4、提取出各个游戏的属性信息后,如何保存(mysql)、生成日报(html)、发送日报(email)?
  5、根据抓取到的游戏属性信息资源,如何查询贵公司的游戏排名(JSP)以及如何清晰的展示游戏排名(JFreeChart图表)?
  6、 更难的是谷歌玩游戏排名没有统一的全球排名。Google 使用本地化策略。数十个国家/地区都有自己的一套排名算法和规则。如何在12个国家实现游戏排名?
  设计方案及技术选择
  分析了上述问题和需求后,如何一一解决并分解,这是我们需要思考、设计和解决的问题(模块流程和技术实现)?
  基于以上分析提出的问题,将一一进行模块设计和技术方案选择如下:
  
  1、为了抓取12个国家的游戏排名,需要分别租用12个国家的代理服务器来抓取各个国家的游戏排名(12个国家的游戏排名算法和语言是不同,包括中文、英文、日文、俄文、西班牙文...)
  2、 抓取网页,使用curl+proxy代理;提取下载的网页信息,使用awk文本分析工具(需要对html语法tag、id等元素有很好的理解才能准确使用awk提取游戏属性信息)
  3、由于IP代理筛选系统、网页抓取程序、游戏属性信息提取等模块都是由脚本完成的,为了保持编程语言的一致性,数据库创建和记录插入也实现了通过 shell 脚本。
  4、 抓取的每款游戏的属性信息,采用html+table的网页形式展示,清晰直观。一个shell脚本用来拼接html字符串(table+tr+td+info)
  5、 生成的html网页会以每日邮件的形式定期发送给产品总监、PM、RD、QA,了解公司发布的游戏排行榜,以及上升最快、最受欢迎的游戏趋势在世界上
  6、 开发JSP网页查询系统,根据输入的游戏名或游戏包名查询某款游戏的排名和趋势,并在趋势图下显示该游戏的所有详细属性信息
  模块技术实现
  1、IP代理过滤
  成本考虑,每个国家租用代理服务器(VPN),以市场最低价1000元/月计算,12000元一年,12个国家的总费用为12x12000=144,000,也就是大约140,000/年的VPN租用需要收费
  基于成本考虑,我后来通过对代理服务器和免费ip的深入研究,提出设计开发一套免费ip代理服务器筛选系统,抓取12个国家的游戏排名。
  免费代理IP主要来自上一篇博客介绍的两个网站:和
  IP代理筛选系统,由于文本预处理和筛选逻辑实现的复杂性,将在下一篇博文中单独介绍
  2、 抓取排名页面
  仔细分析google play游戏排名页面,发现有一定的规律可循:
  第一页的Top24 URL:
  第二页的Top48 URL
  第三页的Top72 URL
  此时,观察每个页面URL的最后一串?start=24&amp;num=24,你已经找到了模式^_^ 其实网页的第一页是从start=0开始的,也可以写成:
  第一页的Top24 URL
  根据上面的规则,可以使用curl+proxy通过循环拼接字符串(start='expr $start + 24')来爬取排名网页
  3、提取游戏链接
  排名页面,每个页面收录24个游戏网址超链接,如何提取这24个游戏网址超链接?
  当时就考虑用xml解析,因为html是一种分层组织的类似xml的格式,但是有些网页并不是所有标准的html格式(比如左括号后没有右括号闭包),这样会导致xml不被正确解析
  后来结合自己学到的html和js知识,分析了爬行排名网页的内容结构,发现每个游戏链接前面都有一个独特的具体格式如下(以篮球投篮为例):
  Basketball Shoot
  这样就可以通过awk顺利提取附近的文本内容,具体实现如下:
  # split url_24
page_key='class="title"'
page_output='output_page.log'
page_output_url_start='https://play.google.com/store/apps/'
page_output_url='output_top800_url.log'
function page_split(){
grep $page_key $(ls $url_output* | sort -t "_" -k6 -n) > tmp_page_grepURL.log # use $url_output
awk -F'[]' '{for(i=1;i> $log
echo "================= $date ================" >> $log


# mysql database and table to create
HOST='localhost'
PORT='3306'
USER='root'
PWD='xxxxxx'
DBNAME='top800'
TABLENAME='gametop800'

mysql_login=''
mysql_create_db=''
mysql_create_table=''


function mysql_create(){
echo "login mysql $HOST:$PORT ..." >> $log
mysql_login="mysql -h $HOST -P $PORT -u $USER -p$PWD" # mysql -h host -P port -u root -p pwd
echo | ${mysql_login}
if [ $? -ne 0 ]; then
echo "login mysql ${HOST}:${PORT} failed.." >> $log
exit 1
else
echo "login mysql ${HOST}:${PORT} success!" >> $log
fi

echo "create database $DBNAME ..." >> $log
mysql_create_db="create database if not exists $DBNAME"
echo ${mysql_create_db} | ${mysql_login}
if [ $? -ne 0 ]; then
echo "create db ${DBNAME} failed.." >> $log
else
echo "create db ${DBNAME} success!" >> $log
fi

echo "create table $TABLENAME ..." >> $log
mysql_create_table="create table $TABLENAME(
id char(50) not null,
url char(255),
top int,
name char(100),
category char(50),
rating char(10),
ratingcount char(20),
download char(30),
price char(20),
publishdate char(20),
version char(40),
filesize char(40),
requireandroid char(40),
contentrating char(40),
country char(10) not null,
dtime date not null default \"2011-01-01\",
primary key(id, country, dtime)
)"

echo ${mysql_create_table} | ${mysql_login} ${DBNAME}
if [ $? -ne 0 ]; then
echo "create table ${TABLENAME} fail..." >> $log
else
echo "create table ${TABLENAME} success!" >> $log
fi
}
  脚本功能说明:
  首先登录mysql数据库,判断mysql服务器、端口号、用户名、密码是否正确。如果不正确,则登录失败退出(exit1);如果正确,则登录成功,继续下一步
  然后,创建数据库名,判断数据库是否存在,如果不存在,则创建;如果存在,继续下一步(注意:创建数据库时,需要验证是否登录数据库成功,否则无法操作)
  最后创建数据库表,首先设计数据库表的各个字段,然后创建数据库表,具体判断方法与创建数据库名称相同
  遍历游戏属性信息文本,全部插入mysql数据库统一存储管理
  # Author : yanggang
# Datetime : 2011.10.24 21:45:09
# ============================================================
#!/bin/sh


# insert mysql
file_input='output_top800_url_page'
file_output='sql_output'

HOST='localhost'
PORT='3306'
USER='root'
PWD='xxxxxx'
DBNAME='top800'
TABLENAME='gametop800'

col_id=''
col_url=''
col_top=1
col_name=''
col_category=''
col_rating=''
col_ratingcount=''
col_download=''
col_price=''
col_publishdate=''
col_version=''
col_filesize=''
col_requireandroid=''
col_contentrating=''
col_country=''
col_dtime=''

sql_insert='insert into gametop800 values("com.mobile.games", "url", 3, "minesweeping",
"games", "4.8", "89789", "1000000-5000000000", "free", "2011-2-30", "1.2.1", "1.5M", "1.5 up", "middle", "china", "2011-10-10")'

function mysql_insert(){
rm -rf $file_output
touch $file_output

DBNAME=$1
col_dtime=$2
col_country=$3
echo 'col_dtime========='$col_dtime

while read line
do
col_id=$(echo $line | cut -f 1 -d "%" | cut -f 1 -d "&" | cut -f 2 -d "=")
col_url=$(echo $line | cut -f 1 -d "%")
col_name=$(echo $line | cut -f 2 -d "%")
col_category=$(echo $line | cut -f 3 -d "%")
col_rating=$(echo $line | cut -f 4 -d "%")
col_ratingcount=$(echo $line | cut -f 5 -d "%")
col_download=$(echo $line | cut -f 6 -d "%")
col_price=$(echo $line | cut -f 7 -d "%")
col_publishdate=$(echo $line | cut -f 8 -d "%")
col_version=$(echo $line | cut -f 9 -d "%")
col_filesize=$(echo $line | cut -f 10 -d "%")
col_requireandroid=$(echo $line | cut -f 11 -d "%")
col_contentrating=$(echo $line | cut -f 12 -d "%")


sql_insert='insert into '$TABLENAME' values('"\"$col_id\", \"$col_url\", $col_top,
\"$col_name\", \"$col_category\", \"$col_rating\", \"$col_ratingcount\", \"$col_download\",
\"$col_price\", \"$col_publishdate\", \"$col_version\", \"$col_filesize\", \"$col_requireandroid\",
\"$col_contentrating\", \"$col_country\", \"$col_dtime\""');'

echo $sql_insert >> $file_output
mysql -h $HOST -P $PORT -u $USER -p$PWD -e "use $DBNAME; $sql_insert"

col_top=`expr $col_top + 1`
done < $file_input
}
  脚本功能说明:
  插入数据库脚本比较简单,主要实现两个功能:游戏排名号(col_top)和数据库语句插入($sql_insert)
  通过while read line循环,读取模块5提取的游戏属性信息文本文件,分割每一行得到对应的字段(cut -f 2 -d "%"),赋值给insert语句(sql_insert)
  最后通过mysql -h $HOST -P $PORT -u $USER-p$PWD -e "use $DBNAME; $sql_insert",登录mysql数据库,执行插入语句$sql_insert
  7、生成HTML报告
  shell 通过连接字符串 table + tr + td + info 来生成 html web 报告。详情请参考我之前的博客:shell将txt转换为html
  8、通过电子邮件发送报告
  邮件发送模块主要采用/usr/bin/mutt的方式。邮件正文显示html报告(默认为美国),其他国家以附件形式发送。详细请参考我之前的博客:linuxshell发送邮件附件
  使用 crontab 命令定期发送电子邮件。具体配置和使用可以参考我之前写的博客:linux定时运行命令script-crontab
  9、网页查询报告
  使用JSP提取MySQL中存储的游戏属性信息,循环生成游戏排名的网页信息,请参考我之前的博客:LinuxJSP连接MySQL数据库
  10、 排名趋势图
  趋势图,使用第三方JFreeChart图表生成工具,请参考我之前的博客:JFreeChart学习实例
  游戏排名趋势图生成后,需要嵌套到JSP网页中进行展示。完整的排名趋势图请参考我之前的博客:JFreeChart Project Example
  自动化主控制脚本
  12国游戏排名系统,免费ip代理过滤——“网络爬虫——”数据库保存——“生成排名报告——”及时发送邮件报告——“游戏排名查询——”趋势图生成
  都实现了整个流程的自动化,以下是各个模块的脚本实现和功能说明:
  
  通过配置服务器的crontab定时运行进程命令,在早上00:01:00(早上0:01:00),主控脚本top10_all.sh会自动启动。
  每天生成的日报使用主控脚本自动生成当天的文件夹,保存当天的抓包数据、分析数据、结果数据,如下图所示:
  
  注:以上文件夹数据为去年测试数据的副本,排名并非本人笔记本截图
  因为通过远程代理爬取12个国家排名前800的TOP800需要消耗网络资源、内存资源和时间,严重影响我的上网体验~~~~(&gt;_ 查看全部

  curl 抓取网页(
其它命令参数用法,同url网址方式,和wget用法)
  
  其他命令参数的用法与url方法相同,这里不再赘述。
  更多curl和wget的用法如ftp协议、迭代子目录等,可以查看man中的帮助手册
  知识拓展:
  在国内,由于某些原因,一般很难直接访问一些敏感的海外网站,需要通过VPN或代理服务器访问。
  如果校园网和教育网有IPv6,可以通过免费代理访问facebook、twitter、六维空间等网站
  其实除了VPN和IPv6+代理方式,普通用户还有其他方式访问国外网站
  这里有两个著名的自由球员网站:
  (全球数十个国家的自由代理,每日更新)
  (通过设置端口类型、代理类型、国家名称过滤)
  curl 项目示例
  使用curl+free agent实现全球12个国家googleplay游戏排名的网页抓取和趋势图查询(抓取网页模块全部用Shell编写,核心代码1000行左右)
  爬取google play游戏排名网页,首先需要分析网页的特点和规律:
  1、Google play游戏排名页面是“总分”格式,即一个页面URL显示了几个排名(比如24),这样的页面有几个构成了所有游戏的总排名
  2、 在每个页面的URL中,点击每个单独的游戏链接可以查看游戏的属性信息(如评分星级、发布日期、版本号、SDK版本号、游戏类别、下载量等)
  需要解决的问题:
  1、如何抓取所有游戏的总排名?
  2、抓取整体排名后,如何拼接网址抓取各个单独的游戏页面?
  3、获取各个单独的游戏网页后,如何提取网页中游戏的属性信息(即评分星级、发布日期...)?
  4、提取出各个游戏的属性信息后,如何保存(mysql)、生成日报(html)、发送日报(email)?
  5、根据抓取到的游戏属性信息资源,如何查询贵公司的游戏排名(JSP)以及如何清晰的展示游戏排名(JFreeChart图表)?
  6、 更难的是谷歌玩游戏排名没有统一的全球排名。Google 使用本地化策略。数十个国家/地区都有自己的一套排名算法和规则。如何在12个国家实现游戏排名?
  设计方案及技术选择
  分析了上述问题和需求后,如何一一解决并分解,这是我们需要思考、设计和解决的问题(模块流程和技术实现)?
  基于以上分析提出的问题,将一一进行模块设计和技术方案选择如下:
  
  1、为了抓取12个国家的游戏排名,需要分别租用12个国家的代理服务器来抓取各个国家的游戏排名(12个国家的游戏排名算法和语言是不同,包括中文、英文、日文、俄文、西班牙文...)
  2、 抓取网页,使用curl+proxy代理;提取下载的网页信息,使用awk文本分析工具(需要对html语法tag、id等元素有很好的理解才能准确使用awk提取游戏属性信息)
  3、由于IP代理筛选系统、网页抓取程序、游戏属性信息提取等模块都是由脚本完成的,为了保持编程语言的一致性,数据库创建和记录插入也实现了通过 shell 脚本。
  4、 抓取的每款游戏的属性信息,采用html+table的网页形式展示,清晰直观。一个shell脚本用来拼接html字符串(table+tr+td+info)
  5、 生成的html网页会以每日邮件的形式定期发送给产品总监、PM、RD、QA,了解公司发布的游戏排行榜,以及上升最快、最受欢迎的游戏趋势在世界上
  6、 开发JSP网页查询系统,根据输入的游戏名或游戏包名查询某款游戏的排名和趋势,并在趋势图下显示该游戏的所有详细属性信息
  模块技术实现
  1、IP代理过滤
  成本考虑,每个国家租用代理服务器(VPN),以市场最低价1000元/月计算,12000元一年,12个国家的总费用为12x12000=144,000,也就是大约140,000/年的VPN租用需要收费
  基于成本考虑,我后来通过对代理服务器和免费ip的深入研究,提出设计开发一套免费ip代理服务器筛选系统,抓取12个国家的游戏排名。
  免费代理IP主要来自上一篇博客介绍的两个网站:和
  IP代理筛选系统,由于文本预处理和筛选逻辑实现的复杂性,将在下一篇博文中单独介绍
  2、 抓取排名页面
  仔细分析google play游戏排名页面,发现有一定的规律可循:
  第一页的Top24 URL:
  第二页的Top48 URL
  第三页的Top72 URL
  此时,观察每个页面URL的最后一串?start=24&amp;num=24,你已经找到了模式^_^ 其实网页的第一页是从start=0开始的,也可以写成:
  第一页的Top24 URL
  根据上面的规则,可以使用curl+proxy通过循环拼接字符串(start='expr $start + 24')来爬取排名网页
  3、提取游戏链接
  排名页面,每个页面收录24个游戏网址超链接,如何提取这24个游戏网址超链接?
  当时就考虑用xml解析,因为html是一种分层组织的类似xml的格式,但是有些网页并不是所有标准的html格式(比如左括号后没有右括号闭包),这样会导致xml不被正确解析
  后来结合自己学到的html和js知识,分析了爬行排名网页的内容结构,发现每个游戏链接前面都有一个独特的具体格式如下(以篮球投篮为例):
  Basketball Shoot
  这样就可以通过awk顺利提取附近的文本内容,具体实现如下:
  # split url_24
page_key='class="title"'
page_output='output_page.log'
page_output_url_start='https://play.google.com/store/apps/'
page_output_url='output_top800_url.log'
function page_split(){
grep $page_key $(ls $url_output* | sort -t "_" -k6 -n) > tmp_page_grepURL.log # use $url_output
awk -F'[]' '{for(i=1;i> $log
echo "================= $date ================" >> $log


# mysql database and table to create
HOST='localhost'
PORT='3306'
USER='root'
PWD='xxxxxx'
DBNAME='top800'
TABLENAME='gametop800'

mysql_login=''
mysql_create_db=''
mysql_create_table=''


function mysql_create(){
echo "login mysql $HOST:$PORT ..." >> $log
mysql_login="mysql -h $HOST -P $PORT -u $USER -p$PWD" # mysql -h host -P port -u root -p pwd
echo | ${mysql_login}
if [ $? -ne 0 ]; then
echo "login mysql ${HOST}:${PORT} failed.." >> $log
exit 1
else
echo "login mysql ${HOST}:${PORT} success!" >> $log
fi

echo "create database $DBNAME ..." >> $log
mysql_create_db="create database if not exists $DBNAME"
echo ${mysql_create_db} | ${mysql_login}
if [ $? -ne 0 ]; then
echo "create db ${DBNAME} failed.." >> $log
else
echo "create db ${DBNAME} success!" >> $log
fi

echo "create table $TABLENAME ..." >> $log
mysql_create_table="create table $TABLENAME(
id char(50) not null,
url char(255),
top int,
name char(100),
category char(50),
rating char(10),
ratingcount char(20),
download char(30),
price char(20),
publishdate char(20),
version char(40),
filesize char(40),
requireandroid char(40),
contentrating char(40),
country char(10) not null,
dtime date not null default \"2011-01-01\",
primary key(id, country, dtime)
)"

echo ${mysql_create_table} | ${mysql_login} ${DBNAME}
if [ $? -ne 0 ]; then
echo "create table ${TABLENAME} fail..." >> $log
else
echo "create table ${TABLENAME} success!" >> $log
fi
}
  脚本功能说明:
  首先登录mysql数据库,判断mysql服务器、端口号、用户名、密码是否正确。如果不正确,则登录失败退出(exit1);如果正确,则登录成功,继续下一步
  然后,创建数据库名,判断数据库是否存在,如果不存在,则创建;如果存在,继续下一步(注意:创建数据库时,需要验证是否登录数据库成功,否则无法操作)
  最后创建数据库表,首先设计数据库表的各个字段,然后创建数据库表,具体判断方法与创建数据库名称相同
  遍历游戏属性信息文本,全部插入mysql数据库统一存储管理
  # Author : yanggang
# Datetime : 2011.10.24 21:45:09
# ============================================================
#!/bin/sh


# insert mysql
file_input='output_top800_url_page'
file_output='sql_output'

HOST='localhost'
PORT='3306'
USER='root'
PWD='xxxxxx'
DBNAME='top800'
TABLENAME='gametop800'

col_id=''
col_url=''
col_top=1
col_name=''
col_category=''
col_rating=''
col_ratingcount=''
col_download=''
col_price=''
col_publishdate=''
col_version=''
col_filesize=''
col_requireandroid=''
col_contentrating=''
col_country=''
col_dtime=''

sql_insert='insert into gametop800 values("com.mobile.games", "url", 3, "minesweeping",
"games", "4.8", "89789", "1000000-5000000000", "free", "2011-2-30", "1.2.1", "1.5M", "1.5 up", "middle", "china", "2011-10-10")'

function mysql_insert(){
rm -rf $file_output
touch $file_output

DBNAME=$1
col_dtime=$2
col_country=$3
echo 'col_dtime========='$col_dtime

while read line
do
col_id=$(echo $line | cut -f 1 -d "%" | cut -f 1 -d "&" | cut -f 2 -d "=")
col_url=$(echo $line | cut -f 1 -d "%")
col_name=$(echo $line | cut -f 2 -d "%")
col_category=$(echo $line | cut -f 3 -d "%")
col_rating=$(echo $line | cut -f 4 -d "%")
col_ratingcount=$(echo $line | cut -f 5 -d "%")
col_download=$(echo $line | cut -f 6 -d "%")
col_price=$(echo $line | cut -f 7 -d "%")
col_publishdate=$(echo $line | cut -f 8 -d "%")
col_version=$(echo $line | cut -f 9 -d "%")
col_filesize=$(echo $line | cut -f 10 -d "%")
col_requireandroid=$(echo $line | cut -f 11 -d "%")
col_contentrating=$(echo $line | cut -f 12 -d "%")


sql_insert='insert into '$TABLENAME' values('"\"$col_id\", \"$col_url\", $col_top,
\"$col_name\", \"$col_category\", \"$col_rating\", \"$col_ratingcount\", \"$col_download\",
\"$col_price\", \"$col_publishdate\", \"$col_version\", \"$col_filesize\", \"$col_requireandroid\",
\"$col_contentrating\", \"$col_country\", \"$col_dtime\""');'

echo $sql_insert >> $file_output
mysql -h $HOST -P $PORT -u $USER -p$PWD -e "use $DBNAME; $sql_insert"

col_top=`expr $col_top + 1`
done < $file_input
}
  脚本功能说明:
  插入数据库脚本比较简单,主要实现两个功能:游戏排名号(col_top)和数据库语句插入($sql_insert)
  通过while read line循环,读取模块5提取的游戏属性信息文本文件,分割每一行得到对应的字段(cut -f 2 -d "%"),赋值给insert语句(sql_insert)
  最后通过mysql -h $HOST -P $PORT -u $USER-p$PWD -e "use $DBNAME; $sql_insert",登录mysql数据库,执行插入语句$sql_insert
  7、生成HTML报告
  shell 通过连接字符串 table + tr + td + info 来生成 html web 报告。详情请参考我之前的博客:shell将txt转换为html
  8、通过电子邮件发送报告
  邮件发送模块主要采用/usr/bin/mutt的方式。邮件正文显示html报告(默认为美国),其他国家以附件形式发送。详细请参考我之前的博客:linuxshell发送邮件附件
  使用 crontab 命令定期发送电子邮件。具体配置和使用可以参考我之前写的博客:linux定时运行命令script-crontab
  9、网页查询报告
  使用JSP提取MySQL中存储的游戏属性信息,循环生成游戏排名的网页信息,请参考我之前的博客:LinuxJSP连接MySQL数据库
  10、 排名趋势图
  趋势图,使用第三方JFreeChart图表生成工具,请参考我之前的博客:JFreeChart学习实例
  游戏排名趋势图生成后,需要嵌套到JSP网页中进行展示。完整的排名趋势图请参考我之前的博客:JFreeChart Project Example
  自动化主控制脚本
  12国游戏排名系统,免费ip代理过滤——“网络爬虫——”数据库保存——“生成排名报告——”及时发送邮件报告——“游戏排名查询——”趋势图生成
  都实现了整个流程的自动化,以下是各个模块的脚本实现和功能说明:
  
  通过配置服务器的crontab定时运行进程命令,在早上00:01:00(早上0:01:00),主控脚本top10_all.sh会自动启动。
  每天生成的日报使用主控脚本自动生成当天的文件夹,保存当天的抓包数据、分析数据、结果数据,如下图所示:
  
  注:以上文件夹数据为去年测试数据的副本,排名并非本人笔记本截图
  因为通过远程代理爬取12个国家排名前800的TOP800需要消耗网络资源、内存资源和时间,严重影响我的上网体验~~~~(&gt;_

curl 抓取网页(块传输编码(ChunkedTransfer)改变消息主体(图) )

网站优化优采云 发表了文章 • 0 个评论 • 65 次浏览 • 2021-09-22 07:06 • 来自相关话题

  curl 抓取网页(块传输编码(ChunkedTransfer)改变消息主体(图)
)
  块传输代码
  chunked编码更改消息正文使消息正文(消息正文,消息正文与实体身体不同,并且将引入以下章节)块传输。每个块都有自己的尺寸(大小)指示器,它立即成为所有块之后收录实体头的可选剪辑。这允许发送传输以动态生成内容,并且可以携带有用的信息,这允许收件人确定消息是否完整。
  4、 curl可以支持在指定要下载的链接时支持URL的序列或集合,并且WGET不能像这样。
  5、 wget支持递归下载,卷曲没有此功能。
  二、网站 crawling实例
  爬网页面,分为URL URL和代理代理。以百度主页为例。
  1、 url url方法爬网
  (1) curl下载百度归属页面内容,保存在百度_html文件中
  curl http://www.baidu.com/ -o baidu_html
  (2) wget下载百度家庭内容,保存在Baidu_html文件中
  wget http://www.baidu.com/ -O baidu_html
  有时,由于网络速度/数据包丢失/服务器停机/等等,有必要临时下载网页。此时,您可能需要多次发送连接,请求服务器响应;如果您仍然没有回复,则可以确认服务器存在问题。
  (1) curl多次尝试
  curl --retry 10 --retry-delay 60 --retry-max-time 60 http://www.baidu.com/ -o baidu_html
  注意:--retry表示重试次数; - 延迟指示两个重试之间的间隔(单位:秒); - 重试 - 最大时间意味着超时。
  curl -y 60 -Y 1 -m 60 http://www.baidu.com -o baidu_html
  注意:-y表示测试网络的时间; - 我表示停止传输速度的限制(单位:字节/秒); - m表示最大连接时间,超出连接自动断开连接以放弃连接
  (2) wget多次尝试
  wget -t 10 -w 60 -T 30 http://www.baidu.com/ -O baidu_html
  注意:-t(-tries)表示扭转数量; -w表示两次重试之间的时间间隔; - t表示链接超时。
  2、代理代理爬网
  代理代理下载,是间接通过连接中间服务器下载URL网页的过程,而不是URL直接连接网站 Server下载。这里的代理使用12 7.0.0. 1:8080来测试。
  (1) curl捕获百度家“
  curl -x 127.0.0.1:8080 -o baidu_html http://www.baidu.com
  注意:-x表示代理服务器(IP:端口),端口频率为80,8080,8086,8888,3128等,默认为80,即卷曲首先连接到代理服务器12 7.0.0. 1:8080,然后下载百度主页,最后12 7.@@@ @ 1:8080通过下载的百度家卷曲到本地
  (2) wget通过代理商抓住百度家
  通过代理下载,使用curl也不是,您需要设置http_proxy = IP:端口
  代理服务器的
  首先。
  以Ubuntu为例,在当前用户目录(CD〜)中,创建一个新的WGet配置文件(.wgetrc),输入代理配置:
  http_proxy=127.0.0.1:8080
  然后输入WGET CRAWLER命令:
  wget http://www.baidu.com -O baidu_html 查看全部

  curl 抓取网页(块传输编码(ChunkedTransfer)改变消息主体(图)
)
  块传输代码
  chunked编码更改消息正文使消息正文(消息正文,消息正文与实体身体不同,并且将引入以下章节)块传输。每个块都有自己的尺寸(大小)指示器,它立即成为所有块之后收录实体头的可选剪辑。这允许发送传输以动态生成内容,并且可以携带有用的信息,这允许收件人确定消息是否完整。
  4、 curl可以支持在指定要下载的链接时支持URL的序列或集合,并且WGET不能像这样。
  5、 wget支持递归下载,卷曲没有此功能。
  二、网站 crawling实例
  爬网页面,分为URL URL和代理代理。以百度主页为例。
  1、 url url方法爬网
  (1) curl下载百度归属页面内容,保存在百度_html文件中
  curl http://www.baidu.com/ -o baidu_html
  (2) wget下载百度家庭内容,保存在Baidu_html文件中
  wget http://www.baidu.com/ -O baidu_html
  有时,由于网络速度/数据包丢失/服务器停机/等等,有必要临时下载网页。此时,您可能需要多次发送连接,请求服务器响应;如果您仍然没有回复,则可以确认服务器存在问题。
  (1) curl多次尝试
  curl --retry 10 --retry-delay 60 --retry-max-time 60 http://www.baidu.com/ -o baidu_html
  注意:--retry表示重试次数; - 延迟指示两个重试之间的间隔(单位:秒); - 重试 - 最大时间意味着超时。
  curl -y 60 -Y 1 -m 60 http://www.baidu.com -o baidu_html
  注意:-y表示测试网络的时间; - 我表示停止传输速度的限制(单位:字节/秒); - m表示最大连接时间,超出连接自动断开连接以放弃连接
  (2) wget多次尝试
  wget -t 10 -w 60 -T 30 http://www.baidu.com/ -O baidu_html
  注意:-t(-tries)表示扭转数量; -w表示两次重试之间的时间间隔; - t表示链接超时。
  2、代理代理爬网
  代理代理下载,是间接通过连接中间服务器下载URL网页的过程,而不是URL直接连接网站 Server下载。这里的代理使用12 7.0.0. 1:8080来测试。
  (1) curl捕获百度家“
  curl -x 127.0.0.1:8080 -o baidu_html http://www.baidu.com
  注意:-x表示代理服务器(IP:端口),端口频率为80,8080,8086,8888,3128等,默认为80,即卷曲首先连接到代理服务器12 7.0.0. 1:8080,然后下载百度主页,最后12 7.@@@ @ 1:8080通过下载的百度家卷曲到本地
  (2) wget通过代理商抓住百度家
  通过代理下载,使用curl也不是,您需要设置http_proxy = IP:端口
  代理服务器的
  首先。
  以Ubuntu为例,在当前用户目录(CD〜)中,创建一个新的WGet配置文件(.wgetrc),输入代理配置:
  http_proxy=127.0.0.1:8080
  然后输入WGET CRAWLER命令:
  wget http://www.baidu.com -O baidu_html

curl 抓取网页(PHP利用CurlFunctions实现并发多线程下载文件(一) )

网站优化优采云 发表了文章 • 0 个评论 • 86 次浏览 • 2021-09-15 01:04 • 来自相关话题

  curl 抓取网页(PHP利用CurlFunctions实现并发多线程下载文件(一)
)
  本文文章主要介绍基于curl的PHP实现多线程爬取。有兴趣的可以参考一下,希望对大家有帮助。
  PHP可以使用Curl来完成各种文件传输操作,比如模拟浏览器发送GET、POST请求等,但是由于PHP语言本身不支持多线程,所以开发爬虫程序的效率不高,所以经常需要Curl。 Multi Functions 该函数实现多线程并发访问多个URL地址,实现多线程并发抓取网页或下载文件
  代码如下:
  再看几个例子
  (1)以下代码是抓取多个网址,然后将抓取到的网址的页面代码写入指定文件
  $urls = array(
&#39;http://www.jb51.net/&#39;,
&#39;http://www.google.com/&#39;,
&#39;http://www.example.com/&#39;
); // 设置要抓取的页面URL
$save_to=&#39;/test.txt&#39;; // 把抓取的代码写入该文件
$st = fopen($save_to,"a");
$mh = curl_multi_init();
foreach ($urls as $i => $url) {
$conn[$i] = curl_init($url);
curl_setopt($conn[$i], CURLOPT_USERAGENT, "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0)");
curl_setopt($conn[$i], CURLOPT_HEADER ,0);
curl_setopt($conn[$i], CURLOPT_CONNECTTIMEOUT,60);
curl_setopt($conn[$i], CURLOPT_FILE,$st); // 将爬取的代码写入文件
curl_multi_add_handle ($mh,$conn[$i]);
} // 初始化
do {
curl_multi_exec($mh,$active);
} while ($active); // 执行
foreach ($urls as $i => $url) {
curl_multi_remove_handle($mh,$conn[$i]);
curl_close($conn[$i]);
} // 结束清理
curl_multi_close($mh);
fclose($st);
  (2)下面的代码和上面的意思一样,只不过这个地方先把获取的代码放入变量中,然后将获取的内容写入指定的文件
  $urls = array(
&#39;http://www.jb51.net/&#39;,
&#39;http://www.google.com/&#39;,
&#39;http://www.example.com/&#39;
);
$save_to=&#39;/test.txt&#39;; // 把抓取的代码写入该文件
$st = fopen($save_to,"a");
$mh = curl_multi_init();
foreach ($urls as $i => $url) {
$conn[$i] = curl_init($url);
curl_setopt($conn[$i], CURLOPT_USERAGENT, "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0)");
curl_setopt($conn[$i], CURLOPT_HEADER ,0);
curl_setopt($conn[$i], CURLOPT_CONNECTTIMEOUT,60);
curl_setopt($conn[$i],CURLOPT_RETURNTRANSFER,true); // 不将爬取代码写到浏览器,而是转化为字符串
curl_multi_add_handle ($mh,$conn[$i]);
}
do {
curl_multi_exec($mh,$active);
} while ($active);
foreach ($urls as $i => $url) {
$data = curl_multi_getcontent($conn[$i]); // 获得爬取的代码字符串
fwrite($st,$data); // 将字符串写入文件
} // 获得数据变量,并写入文件
foreach ($urls as $i => $url) {
curl_multi_remove_handle($mh,$conn[$i]);
curl_close($conn[$i]);
}
curl_multi_close($mh);
fclose($st);
  (3)以下代码实现使用PHP的Curl Functions实现文件的并发多线程下载
  $urls=array(
&#39;http://www.jb51.net/5w.zip&#39;,
&#39;http://www.jb51.net/5w.zip&#39;,
&#39;http://www.jb51.net/5w.zip&#39;
);
$save_to=&#39;./home/&#39;;
$mh=curl_multi_init();
foreach($urls as $i=>$url){
$g=$save_to.basename($url);
if(!is_file($g)){
$conn[$i]=curl_init($url);
$fp[$i]=fopen($g,"w");
curl_setopt($conn[$i],CURLOPT_USERAGENT,"Mozilla/4.0(compatible; MSIE 7.0; Windows NT 6.0)");
curl_setopt($conn[$i],CURLOPT_FILE,$fp[$i]);
curl_setopt($conn[$i],CURLOPT_HEADER ,0);
curl_setopt($conn[$i],CURLOPT_CONNECTTIMEOUT,60);
curl_multi_add_handle($mh,$conn[$i]);
}
}
do{
$n=curl_multi_exec($mh,$active);
}while($active);
foreach($urls as $i=>$url){
curl_multi_remove_handle($mh,$conn[$i]);
curl_close($conn[$i]);
fclose($fp[$i]);
}
curl_multi_close($mh);$urls=array(
&#39;http://www.jb51.net/5w.zip&#39;,
&#39;http://www.jb51.net/5w.zip&#39;,
&#39;http://www.jb51.net/5w.zip&#39;
);
$save_to=&#39;./home/&#39;;
$mh=curl_multi_init();
foreach($urls as $i=>$url){
$g=$save_to.basename($url);
if(!is_file($g)){
$conn[$i]=curl_init($url);
$fp[$i]=fopen($g,"w");
curl_setopt($conn[$i],CURLOPT_USERAGENT,"Mozilla/4.0(compatible; MSIE 7.0; Windows NT 6.0)");
curl_setopt($conn[$i],CURLOPT_FILE,$fp[$i]);
curl_setopt($conn[$i],CURLOPT_HEADER ,0);
curl_setopt($conn[$i],CURLOPT_CONNECTTIMEOUT,60);
curl_multi_add_handle($mh,$conn[$i]);
}
}
do{
$n=curl_multi_exec($mh,$active);
}while($active);
foreach($urls as $i=>$url){
curl_multi_remove_handle($mh,$conn[$i]);
curl_close($conn[$i]);
fclose($fp[$i]);
}
curl_multi_close($mh); 查看全部

  curl 抓取网页(PHP利用CurlFunctions实现并发多线程下载文件(一)
)
  本文文章主要介绍基于curl的PHP实现多线程爬取。有兴趣的可以参考一下,希望对大家有帮助。
  PHP可以使用Curl来完成各种文件传输操作,比如模拟浏览器发送GET、POST请求等,但是由于PHP语言本身不支持多线程,所以开发爬虫程序的效率不高,所以经常需要Curl。 Multi Functions 该函数实现多线程并发访问多个URL地址,实现多线程并发抓取网页或下载文件
  代码如下:
  再看几个例子
  (1)以下代码是抓取多个网址,然后将抓取到的网址的页面代码写入指定文件
  $urls = array(
&#39;http://www.jb51.net/&#39;,
&#39;http://www.google.com/&#39;,
&#39;http://www.example.com/&#39;
); // 设置要抓取的页面URL
$save_to=&#39;/test.txt&#39;; // 把抓取的代码写入该文件
$st = fopen($save_to,"a");
$mh = curl_multi_init();
foreach ($urls as $i => $url) {
$conn[$i] = curl_init($url);
curl_setopt($conn[$i], CURLOPT_USERAGENT, "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0)");
curl_setopt($conn[$i], CURLOPT_HEADER ,0);
curl_setopt($conn[$i], CURLOPT_CONNECTTIMEOUT,60);
curl_setopt($conn[$i], CURLOPT_FILE,$st); // 将爬取的代码写入文件
curl_multi_add_handle ($mh,$conn[$i]);
} // 初始化
do {
curl_multi_exec($mh,$active);
} while ($active); // 执行
foreach ($urls as $i => $url) {
curl_multi_remove_handle($mh,$conn[$i]);
curl_close($conn[$i]);
} // 结束清理
curl_multi_close($mh);
fclose($st);
  (2)下面的代码和上面的意思一样,只不过这个地方先把获取的代码放入变量中,然后将获取的内容写入指定的文件
  $urls = array(
&#39;http://www.jb51.net/&#39;,
&#39;http://www.google.com/&#39;,
&#39;http://www.example.com/&#39;
);
$save_to=&#39;/test.txt&#39;; // 把抓取的代码写入该文件
$st = fopen($save_to,"a");
$mh = curl_multi_init();
foreach ($urls as $i => $url) {
$conn[$i] = curl_init($url);
curl_setopt($conn[$i], CURLOPT_USERAGENT, "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0)");
curl_setopt($conn[$i], CURLOPT_HEADER ,0);
curl_setopt($conn[$i], CURLOPT_CONNECTTIMEOUT,60);
curl_setopt($conn[$i],CURLOPT_RETURNTRANSFER,true); // 不将爬取代码写到浏览器,而是转化为字符串
curl_multi_add_handle ($mh,$conn[$i]);
}
do {
curl_multi_exec($mh,$active);
} while ($active);
foreach ($urls as $i => $url) {
$data = curl_multi_getcontent($conn[$i]); // 获得爬取的代码字符串
fwrite($st,$data); // 将字符串写入文件
} // 获得数据变量,并写入文件
foreach ($urls as $i => $url) {
curl_multi_remove_handle($mh,$conn[$i]);
curl_close($conn[$i]);
}
curl_multi_close($mh);
fclose($st);
  (3)以下代码实现使用PHP的Curl Functions实现文件的并发多线程下载
  $urls=array(
&#39;http://www.jb51.net/5w.zip&#39;,
&#39;http://www.jb51.net/5w.zip&#39;,
&#39;http://www.jb51.net/5w.zip&#39;
);
$save_to=&#39;./home/&#39;;
$mh=curl_multi_init();
foreach($urls as $i=>$url){
$g=$save_to.basename($url);
if(!is_file($g)){
$conn[$i]=curl_init($url);
$fp[$i]=fopen($g,"w");
curl_setopt($conn[$i],CURLOPT_USERAGENT,"Mozilla/4.0(compatible; MSIE 7.0; Windows NT 6.0)");
curl_setopt($conn[$i],CURLOPT_FILE,$fp[$i]);
curl_setopt($conn[$i],CURLOPT_HEADER ,0);
curl_setopt($conn[$i],CURLOPT_CONNECTTIMEOUT,60);
curl_multi_add_handle($mh,$conn[$i]);
}
}
do{
$n=curl_multi_exec($mh,$active);
}while($active);
foreach($urls as $i=>$url){
curl_multi_remove_handle($mh,$conn[$i]);
curl_close($conn[$i]);
fclose($fp[$i]);
}
curl_multi_close($mh);$urls=array(
&#39;http://www.jb51.net/5w.zip&#39;,
&#39;http://www.jb51.net/5w.zip&#39;,
&#39;http://www.jb51.net/5w.zip&#39;
);
$save_to=&#39;./home/&#39;;
$mh=curl_multi_init();
foreach($urls as $i=>$url){
$g=$save_to.basename($url);
if(!is_file($g)){
$conn[$i]=curl_init($url);
$fp[$i]=fopen($g,"w");
curl_setopt($conn[$i],CURLOPT_USERAGENT,"Mozilla/4.0(compatible; MSIE 7.0; Windows NT 6.0)");
curl_setopt($conn[$i],CURLOPT_FILE,$fp[$i]);
curl_setopt($conn[$i],CURLOPT_HEADER ,0);
curl_setopt($conn[$i],CURLOPT_CONNECTTIMEOUT,60);
curl_multi_add_handle($mh,$conn[$i]);
}
}
do{
$n=curl_multi_exec($mh,$active);
}while($active);
foreach($urls as $i=>$url){
curl_multi_remove_handle($mh,$conn[$i]);
curl_close($conn[$i]);
fclose($fp[$i]);
}
curl_multi_close($mh);

curl 抓取网页(curl抓取网页的执行命令-|curl--)

网站优化优采云 发表了文章 • 0 个评论 • 82 次浏览 • 2021-09-13 03:01 • 来自相关话题

  curl 抓取网页(curl抓取网页的执行命令-|curl--)
  curl抓取网页
  1、执行命令:|bash-
  2、执行命令:||bash-
  4、服务管理中的curl命令:curl-a/some/documents/test/config/config.xml/some/documents/test/config.xml
  6、scheme环境:选择当前用户下的前100个scheme,
  7、curl的网址判断:echo123"http"一开始会报错,但是只要你把服务器的443端口号改为80,就可以输入123如果你没有改123端口号,那就是表示百度的网址,下次换一个试试例如:curl-e"123。160。99。136"|bash因为是从远程连接的,所以不会出错,但是如果远程没有改为123,或者改了443端口号还是没有输入www是以域名来访问网页curl的命令输入窗口的按键是fn命令fn功能请自行脑补。
  个人一般在windows环境下写脚本,用msf打开shell文件不好,更别说shell中还要加上编辑功能。
  登录的话就抓shellcode用爬虫,
  cmd命令行就可以, 查看全部

  curl 抓取网页(curl抓取网页的执行命令-|curl--)
  curl抓取网页
  1、执行命令:|bash-
  2、执行命令:||bash-
  4、服务管理中的curl命令:curl-a/some/documents/test/config/config.xml/some/documents/test/config.xml
  6、scheme环境:选择当前用户下的前100个scheme,
  7、curl的网址判断:echo123"http"一开始会报错,但是只要你把服务器的443端口号改为80,就可以输入123如果你没有改123端口号,那就是表示百度的网址,下次换一个试试例如:curl-e"123。160。99。136"|bash因为是从远程连接的,所以不会出错,但是如果远程没有改为123,或者改了443端口号还是没有输入www是以域名来访问网页curl的命令输入窗口的按键是fn命令fn功能请自行脑补。
  个人一般在windows环境下写脚本,用msf打开shell文件不好,更别说shell中还要加上编辑功能。
  登录的话就抓shellcode用爬虫,
  cmd命令行就可以,

curl 抓取网页(抓取网页内容,PHP手册真乃圣经也也乃也))

网站优化优采云 发表了文章 • 0 个评论 • 76 次浏览 • 2021-09-09 19:24 • 来自相关话题

  curl 抓取网页(抓取网页内容,PHP手册真乃圣经也也乃也))
  获取网页内容,PHP有几个可以实现的内置函数,比如file()、file_get_contents()等,都支持URL参数。但要实现更复杂的操作,这些功能就无能为力了。
  cURL 是一个文件传输工具,它使用 URL 语法在命令行下工作。 cURL 提供了一个 PHP 扩展。有了这个扩展,你可以完全模拟浏览器操作,就像使用浏览器浏览网页一样。可以设置header内容、设置cookie数据、POST数据、上传文件、设置代理等,其实我们这里讨论的爬取网页内容只是其常用的应用之一。
  cURL 官方网站:
  PHP cURL 扩展:
  在Windows下添加这个扩展很简单,加载php_curl.dll即可。去掉php.ini文件extension=php_curl.dll前面的分号,将php_curl.dll复制到PHP扩展目录下或者重启C:\Windows\system32目录下的Web服务器。 php_curl.dll 在 PHP 的 ZIP 包中提供。
  Linux下,需要先安装cURL。一种方法是编译成PHP,编译配置时加上--with-curl[=DIR]。另一种方法是编译成PHP模块加载,编译cURL模块的方法和编译其他PHP模块的方法是一样的。以下是基本命令:
  cd /path/to/php/source 进入PHP源代码目录
  cd ext/curl 进入cURL模块源码目录
  /usr/local/php/bin/phpize 生成编译配置文件
  ./configure --with-php-config=/usr/local/php/bin/php-config
  制作
  进行安装
  编译完成生成curl.so,修改php.ini,加载模块:
  extension="/path/to/extension/curl.so"
  测试cURL扩展是否加载,新建PHP文件:
  抓取网页示例:
  curl_setopt() 可以设置很多选项。更多选项请参考PHP手册。
  更多的功能和用法请参考PHP手册(再次废话,强调PHP手册真的是一本圣经)。
  2010-12-06 更新
  ============
  当前,移动互联网发展迅猛。很多门户网站都开发了手机网站,比如腾讯()、新浪()、网易()、搜狐(),一般的手机网站都会对浏览器的User Agent进行检测做出相应的适应。但是用户代理不是很可靠,因为它是从客户端发送到服务器的。我们可以通过各种方式伪造用户代理。 Firefox 有一个插件 User Agent Switcher()(这个主页在中国可能无法访问。翻墙)就是这样一个工具。当然,本文讨论的cURL也可以做到这一点。在开发过程中,我们可能需要伪造用户代理。以下是几款主流平台智能手机自带浏览器的User Agent。
  诺基亚 E71(S60 第三版):
  Mozilla/5.0 (SymbianOS/9.2; U; Series60/3.1 NokiaE71/1.00.000; Profile/MIDP-2.0 Configuration/CLDC-1.1;) AppleWebKit/413(KHTML,如 Gecko)Safari/413
  HTC Desire (安卓2.1/2.2):
  Mozilla/5.0 (Linux; U; Android 2.1-update1; zh-cn; Desire_A8181 Build/ERE27) AppleWebKit/530.17 (KHTML, like Gecko) 版本/4.0 移动版 Safari/530.17
  iPhone 3GS(iOS 3):
  Mozilla/5.0 (iPhone; U; CPU iPhone OS 3_0 like Mac OS X; zh-cn) AppleWebKit/420.1 (KHTML, like Gecko) 版本/3.0 Mobile/1A542a Safari /419.3
  黑莓 8700(黑莓):
  BlackBerry8700/4.1.0 Profile/MIDP-2.0 Configuration/CLDC-1.1 VendorID/100 查看全部

  curl 抓取网页(抓取网页内容,PHP手册真乃圣经也也乃也))
  获取网页内容,PHP有几个可以实现的内置函数,比如file()、file_get_contents()等,都支持URL参数。但要实现更复杂的操作,这些功能就无能为力了。
  cURL 是一个文件传输工具,它使用 URL 语法在命令行下工作。 cURL 提供了一个 PHP 扩展。有了这个扩展,你可以完全模拟浏览器操作,就像使用浏览器浏览网页一样。可以设置header内容、设置cookie数据、POST数据、上传文件、设置代理等,其实我们这里讨论的爬取网页内容只是其常用的应用之一。
  cURL 官方网站:
  PHP cURL 扩展:
  在Windows下添加这个扩展很简单,加载php_curl.dll即可。去掉php.ini文件extension=php_curl.dll前面的分号,将php_curl.dll复制到PHP扩展目录下或者重启C:\Windows\system32目录下的Web服务器。 php_curl.dll 在 PHP 的 ZIP 包中提供。
  Linux下,需要先安装cURL。一种方法是编译成PHP,编译配置时加上--with-curl[=DIR]。另一种方法是编译成PHP模块加载,编译cURL模块的方法和编译其他PHP模块的方法是一样的。以下是基本命令:
  cd /path/to/php/source 进入PHP源代码目录
  cd ext/curl 进入cURL模块源码目录
  /usr/local/php/bin/phpize 生成编译配置文件
  ./configure --with-php-config=/usr/local/php/bin/php-config
  制作
  进行安装
  编译完成生成curl.so,修改php.ini,加载模块:
  extension="/path/to/extension/curl.so"
  测试cURL扩展是否加载,新建PHP文件:
  抓取网页示例:
  curl_setopt() 可以设置很多选项。更多选项请参考PHP手册。
  更多的功能和用法请参考PHP手册(再次废话,强调PHP手册真的是一本圣经)。
  2010-12-06 更新
  ============
  当前,移动互联网发展迅猛。很多门户网站都开发了手机网站,比如腾讯()、新浪()、网易()、搜狐(),一般的手机网站都会对浏览器的User Agent进行检测做出相应的适应。但是用户代理不是很可靠,因为它是从客户端发送到服务器的。我们可以通过各种方式伪造用户代理。 Firefox 有一个插件 User Agent Switcher()(这个主页在中国可能无法访问。翻墙)就是这样一个工具。当然,本文讨论的cURL也可以做到这一点。在开发过程中,我们可能需要伪造用户代理。以下是几款主流平台智能手机自带浏览器的User Agent。
  诺基亚 E71(S60 第三版):
  Mozilla/5.0 (SymbianOS/9.2; U; Series60/3.1 NokiaE71/1.00.000; Profile/MIDP-2.0 Configuration/CLDC-1.1;) AppleWebKit/413(KHTML,如 Gecko)Safari/413
  HTC Desire (安卓2.1/2.2):
  Mozilla/5.0 (Linux; U; Android 2.1-update1; zh-cn; Desire_A8181 Build/ERE27) AppleWebKit/530.17 (KHTML, like Gecko) 版本/4.0 移动版 Safari/530.17
  iPhone 3GS(iOS 3):
  Mozilla/5.0 (iPhone; U; CPU iPhone OS 3_0 like Mac OS X; zh-cn) AppleWebKit/420.1 (KHTML, like Gecko) 版本/3.0 Mobile/1A542a Safari /419.3
  黑莓 8700(黑莓):
  BlackBerry8700/4.1.0 Profile/MIDP-2.0 Configuration/CLDC-1.1 VendorID/100

curl 抓取网页(PHP的调用测试(get(get)函数(图) )

网站优化优采云 发表了文章 • 0 个评论 • 101 次浏览 • 2021-09-09 08:10 • 来自相关话题

  curl 抓取网页(PHP的调用测试(get(get)函数(图)
)
  PHP 的 curl 功能真的很强大。里面有个curl_multi_init函数,就是批处理任务。可以用它来实现多进程同时抓取多条记录,优化常见的网页抓取程序。
  一个简单的获取函数:
  function http_get_multi($urls){
$count = count($urls);
$data = [];
$chs = [];
// 创建批处理cURL句柄
$mh = curl_multi_init();
// 创建cURL资源
for($i = 0; $i < $count; $i ++){
$chs[ $i ] = curl_init();
// 设置URL和相应的选项
curl_setopt($chs[ $i ], CURLOPT_RETURNTRANSFER, 1); // return don‘t print
curl_setopt($chs[ $i ], CURLOPT_URL, $urls[$i]);
curl_setopt($chs[ $i ], CURLOPT_HEADER, 0);
curl_multi_add_handle($mh, $chs[ $i ]);
}
// 增加句柄
// for($i = 0; $i < $count; $i ++){
// curl_multi_add_handle($mh, $chs[ $i ]);
// }
// 执行批处理句柄
do {
$mrc = curl_multi_exec($mh, $active);
} while ($active > 0);
while ($active and $mrc == CURLM_OK) {
if (curl_multi_select($mh) != -1) {
do {
$mrc = curl_multi_exec($mh, $active);
} while ($mrc == CURLM_CALL_MULTI_PERFORM);
}
}
for($i = 0; $i < $count; $i ++){
$content = curl_multi_getcontent($chs[ $i ]);
$data[ $i ] = ( curl_errno($chs[ $i ]) == 0 ) ? $content : false;
}
// 关闭全部句柄
for($i = 0; $i < $count; $i ++){
curl_multi_remove_handle($mh, $chs[ $i ]);
}
curl_multi_close($mh);
return $data;
}
  下面的调用测试(get() 函数就像这里:):
  //弄很多个网页的url<br />$url = [
‘http://www.baidu.com‘,
‘http://www.163.com‘,
‘http://www.sina.com.cn‘,
‘http://www.qq.com‘,
‘http://www.sohu.com‘,
‘http://www.douban.com‘,
‘http://www.cnblogs.com‘,
‘http://www.taobao.com‘,
‘http://www.php.net‘,
];
$urls = [];
for($i = 0; $i < 10; $i ++){
foreach($url as $r)
$urls[] = $r . ‘/?v=‘ . rand();
} <br /><br />//并发请求
$datas = http_get_multi($urls);
foreach($datas as $key => $data){
file_put_contents(‘log/multi_‘ . $key . ‘.txt‘, $data); // 记录一下请求结果。记得创建一个log文件夹
}
$t2 = microtime(true);
echo $t2 - $t1;
echo ‘<br />‘;<br /><br />//同步请求, get()函数如这里: http://www.cnblogs.com/whatmiss/p/7114954.html
$t1 = microtime(true);
foreach($urls as $key => $url){
file_put_contents(‘log/get_‘ . $key . ‘.txt‘, get($url)); // 记录一下请求结果。记得创建一个log文件夹
}
$t2 = microtime(true);
echo $t2 - $t1;
  测试结果显示出明显的差距,随着数据量的增加,差距会呈指数级扩大:
  2.4481401443481
21.68923997879
8.925509929657
24.73141503334
3.243185043335
23.384337902069
3.2841880321503
24.754415035248

3.2091829776764
29.068662881851 查看全部

  curl 抓取网页(PHP的调用测试(get(get)函数(图)
)
  PHP 的 curl 功能真的很强大。里面有个curl_multi_init函数,就是批处理任务。可以用它来实现多进程同时抓取多条记录,优化常见的网页抓取程序。
  一个简单的获取函数:
  function http_get_multi($urls){
$count = count($urls);
$data = [];
$chs = [];
// 创建批处理cURL句柄
$mh = curl_multi_init();
// 创建cURL资源
for($i = 0; $i < $count; $i ++){
$chs[ $i ] = curl_init();
// 设置URL和相应的选项
curl_setopt($chs[ $i ], CURLOPT_RETURNTRANSFER, 1); // return don‘t print
curl_setopt($chs[ $i ], CURLOPT_URL, $urls[$i]);
curl_setopt($chs[ $i ], CURLOPT_HEADER, 0);
curl_multi_add_handle($mh, $chs[ $i ]);
}
// 增加句柄
// for($i = 0; $i < $count; $i ++){
// curl_multi_add_handle($mh, $chs[ $i ]);
// }
// 执行批处理句柄
do {
$mrc = curl_multi_exec($mh, $active);
} while ($active > 0);
while ($active and $mrc == CURLM_OK) {
if (curl_multi_select($mh) != -1) {
do {
$mrc = curl_multi_exec($mh, $active);
} while ($mrc == CURLM_CALL_MULTI_PERFORM);
}
}
for($i = 0; $i < $count; $i ++){
$content = curl_multi_getcontent($chs[ $i ]);
$data[ $i ] = ( curl_errno($chs[ $i ]) == 0 ) ? $content : false;
}
// 关闭全部句柄
for($i = 0; $i < $count; $i ++){
curl_multi_remove_handle($mh, $chs[ $i ]);
}
curl_multi_close($mh);
return $data;
}
  下面的调用测试(get() 函数就像这里:):
  //弄很多个网页的url<br />$url = [
http://www.baidu.com‘,
http://www.163.com‘,
http://www.sina.com.cn‘,
http://www.qq.com‘,
http://www.sohu.com‘,
http://www.douban.com‘,
http://www.cnblogs.com‘,
http://www.taobao.com‘,
http://www.php.net‘,
];
$urls = [];
for($i = 0; $i < 10; $i ++){
foreach($url as $r)
$urls[] = $r . ‘/?v=‘ . rand();
} <br /><br />//并发请求
$datas = http_get_multi($urls);
foreach($datas as $key => $data){
file_put_contents(‘log/multi_‘ . $key . ‘.txt‘, $data); // 记录一下请求结果。记得创建一个log文件夹
}
$t2 = microtime(true);
echo $t2 - $t1;
echo ‘<br />‘;<br /><br />//同步请求, get()函数如这里: http://www.cnblogs.com/whatmiss/p/7114954.html
$t1 = microtime(true);
foreach($urls as $key => $url){
file_put_contents(‘log/get_‘ . $key . ‘.txt‘, get($url)); // 记录一下请求结果。记得创建一个log文件夹
}
$t2 = microtime(true);
echo $t2 - $t1;
  测试结果显示出明显的差距,随着数据量的增加,差距会呈指数级扩大:
  2.4481401443481
21.68923997879
8.925509929657
24.73141503334
3.243185043335
23.384337902069
3.2841880321503
24.754415035248

3.2091829776764
29.068662881851

官方客服QQ群

微信人工客服

QQ人工客服


线