使用wget抓取网页内容,常规用法及有用参数

环境:linux系统(各种发行版皆可),windows下强烈推荐cygwin环境

常规用法:

  1. 直接下载一个文件,默认按最后一级文件名保存到本地: wget {your-url}
  2. 如需自定义保存文件名则增加参数 -O 指定保留文件路径: wget -O {save-file-name} {your-url}
  3. 下载一批文件,把文件路径放到一个文本文件中,每行一个: wget -i {file-name-of-your-filelist}
  4. 下载一个页面及页面中图片等元素,wget -p {your-url}   ,即增加参数 --page-requisites (缩写为-p)
  5. 按网址中目录及文件名存储下载文件,即与源站同样的目录结构,增加参数 --force-directories-x

一些有用参数设置

  1. 指定user-agent 参数: -U {agent-string}--user-agent={agent-string}
  2. 批量下载时设置请求间隔:--wait={秒数}-w {秒数}
  3. 请求随机间隔,增加 --random-wait 参数,将以wait指定秒数0.5-1.5倍随机等待:
  4.  递归下载 -r ,一般还要同时指定--domains, --exclude-domains, --level 等限制下载内容
  5. 同时下载http页面中的图片等元素--page-requisites 缩写为-p
  6. 支持断点续传 -c
  7. 维持请求间的cookie参数 --save-cookies={saved_file_name} ,如需要同时追踪session的cookie,则增加 --keep-session-cookies,如需要加载以前wget保存的cookie,可使用--load-cookies={saved_file_name}
  8. 指定自定义的http头 --header={header-line},多个头则多次指定该参数
  9. 设置网络超时 --timeout={秒数}-T,设置后 --dns-timeout, --connect-timeout, --read-timeout 也将一起设置,当然也可以另外为它们单独设置。

设置代理

wget不支持socks代理,支持http,https,ftp三类代理,分别为https_prox, /http_proxy, ftp_proxy,下面示例只以http_proxy为例。为wget指定代理有三种方法,推荐第三种

  • 设置环境变量 export http_proxy=http://127.0.0.1:8080
  • 配置文件 /etc/wgetrc或 ~/.wgetrc
  • 在wget 命令行中通过 -e参数(临时设置环境变量)-e参数本身是执行命令,与wgetrc中的设置效果相同。示例:-e "http_proxy=http://127.0.0.1:8080"

更多参考

修订于 2019/12/09

--------- 后面是以前的2013年以前的版本,没啥用,不用看了 ------

需要采集一批数据,是一网站上的产品信息,产品本身信息很简单,使用火车采集器轻松实现;但产品价格数据是ajax响应数据,使用firebug + live http headers抓到该请求,并测试重发,发现该ajax请求必须带一个http头“X-Requested-With: XMLHttpRequest”,没有就返回404错误。

gnu/linux下有大量的杀手级工具,这种情况,要动用其中的wget. wget有很多参数,这里需要使用其中两个:-O,--header. 其中:

-O, 把请求结果保存到指定文件,但我们要使用的却是一个特殊的值:“-”,它可以将结果输出到标准输出

--header, 结http请求加上自定义的头(http header)

于是对于每条产品数据,都发送这样的请求:

wget --header="X-Requested-With: XMLHttpRequest" -O save_123.txt "http://www.website.com/request/path/?Id=123"

这样每条产品都保存到save_123.txt,save_124.txt,save_125.txt....这样的一系列文件中。不过有个问题是,每条数据一个文件,后期分析不方便。所以将其存储到单一的文件里。

方案:先将wget结果指向到标准输出,然后再使用重定向符 >> 定向到单一的文件里。

不过,还有一个问题,每个http响应里没有产品id号,数据跟采集到的产品信息对不上号。于是在每写一笔采集结果前,往文件里先写入该产品的id号。

这里使用echo 命令,要用到echo 的参数:-e, 作用是使用转义符输出换行。示例:echo -e "aaa\nbbb"

于是构造这样的bash脚本:

echo -e "\n"10011"\t"  >>data.log ;wget --header="X-Requested-With: XMLHttpRequest" -O- "http://www.website.com/request/path/?Id=10011" >>data.log; 
echo -e "\n"10012"\t"  >>data.log ;wget --header="X-Requested-With: XMLHttpRequest" -O- "http://www.website.com/request/path/?Id=10012" >>data.log; 
echo -e "\n"10013"\t"  >>data.log ;wget --header="X-Requested-With: XMLHttpRequest" -O- "http://www.website.com/request/path/?Id=10013" >>data.log; sheep 1;
echo -e "\n"10014"\t"  >>data.log ;wget --header="X-Requested-With: XMLHttpRequest" -O- "http://www.website.com/request/path/?Id=10014" >>data.log; 
echo -e "\n"10015"\t"  >>data.log ;wget --header="X-Requested-With: XMLHttpRequest" -O- "http://www.website.com/request/path/?Id=10015" >>data.log; 
echo -e "\n"10016"\t"  >>data.log ;wget --header="X-Requested-With: XMLHttpRequest" -O- "http://www.website.com/request/path/?Id=10016" >>data.log; sheep 1;

第三行加一个sheep 1, 即每采三条暂停1秒钟,作用是防止请求过于密集而影响服务器响应,暂停秒数按实际情况设置。

所有数据都保存到data.log文件里,里面格式如下

10011    
{"data":.....}
10012    
{"data":.....}
10013    
{"data":.....}
10014    
{"data":.....}

每两行一笔数据,其中第一行是产品id号,第二行是采集到的数据。这样就可以方便的提取其中数据了。

其实,对于而需要提取的数据,完全可以通过grep从定向到标准输出的wget结果里提取。只是这里不么做了。

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据