爬虫面对如此多重复的标签,应该怎么爬才能爬到自己
二、爬虫工程师需要掌握哪些技能?我见过这样的说法:“爬虫是低级、重复性很多的工作,没有发展前途”。这是误解。首先,对于程序员来说基本上不存在重复性的工作,任何重复劳动都可以通过程序自动解决。例如博主之前要抓十几个相似度很高但是html结构不太一样的网站,我就写了一个简单的代码生成器,从爬虫代码到单元测试代码都可以自动生成,只要对应html结构稍微修改一下就行了。所以我认为,重复性的劳动在编程方面来说基本上是不存在的,如果你认为自己做的工作是重复性的,说明你比较勤快,不愿意去偷懒。而我还认为,勤快的程序员不是好程序员。下面我根据自己这段时间的工作经历,讲一讲爬虫需要哪些相关的技能。1.基本的编码基础(至少一门编程语言)这个对于任何编程工作来说都是必须的。基础的数据结构你得会吧。数据名字和值得对应(字典),对一些url进行处理(列表)等等。事实上,掌握的越牢固越好,爬虫并不是一个简单的工作,也并不比其他工作对编程语言的要求更高。熟悉你用的编程语言,熟悉相关的框架和库永远是无害。我主要用Python,用Java写爬虫的也有,理论上讲任何语言都可以写爬虫的,不过最好选择一门相关的库多,开发迅速的语言。用C语言写肯定是自找苦吃了。2.任务队列当爬虫任务很大的时候,写一个程序跑下来是不合适的:如果中间遇到错误停掉,重头再来?这不科学我怎么知道程序在哪里失败了?任务和任务之间不应该相互影响如果我有两台机器怎么分工?所以我们需要一种任务队列,它的作用是:讲计划抓取的网页都放到任务队列里面去。然后worker从队列中拿出来一个一个执行,如果一个失败,记录一下,然后执行下一个。这样,worker就可以一个接一个地执行下去。也增加了扩展性,几亿个任务放在队列里也没问题,有需要可以增加worker,就像多一双亏筷子吃饭一样。常用的任务队列有kafka,beanstalkd,celery等。3.数据库这个不用讲了,数据保存肯定要会数据库的。不过有时候一些小数据也可以保存成json或者csv等。我有时想抓一些图片就直接按照文件夹保存文件。推荐使用NoSQL的数据库,比如mongodb,因为爬虫抓到的数据一般是都字段-值得对应,有些字段有的网站有有的网站没有,mongo在这方面比较灵活,况且爬虫爬到的数据关系非常非常弱,很少会用到表与表的关系。4.HTTP知识HTTP知识是必备技能。因为要爬的是网页,所以必须要了解网页啊。首先html文档的解析方法要懂,比如子节点父节点,属性这些。我们看到的网页是五彩斑斓的,只不过是被浏览器处理了而已,原始的网页是由很多标签组成的。处理最好使用html的解析器,如果自己用正则匹配的话坑会很多。我个人非常喜欢xpath,跨语言,表达比价好,但是也有缺点,正则、逻辑判断有点别扭。HTTP协议要理解。HTTP协议本身是无状态的,那么“登录”是怎么实现的?这就要求去了解一下session和cookies了。GET方法和POST方法的区别(事实上除了字面意思不一样没有任何区别)。浏览器要熟练。爬虫的过程其实是模拟人类去浏览器数据的过程。所以浏览器是怎么访问一个网站的,你要学会去观察,怎么观察呢?Developer Tools!Chrome的Developer Tools提供了访问网站的一切信息。从traffic可以看到所有发出去的请求。copy as curl功能可以给你生成和浏览器请求完全一致的curl请求!我写一个爬虫的一般流程是这样的,先用浏览器访问,然后copy as curl看看有哪些header,cookies,然后用代码模拟出来这个请求,最后处理请求的结果保存下来。5.运维这个话题要说的有很多,实际工作中运维和开发的时间差不多甚至更多一些。维护已经在工作的爬虫是一个繁重的工作。随着工作时间增加,一般我们都会学着让写出来的爬虫更好维护一些。比如爬虫的日志系统,数据量的统计等。将爬虫工程师和运维分开也不太合理,因为如果一个爬虫不工作了,那原因可能是要抓的网页更新了结构,也有可能出现在系统上,也有可能是当初开发爬虫的时候没发现反扒策略,上线之后出问题了,也可能是对方网站发现了你是爬虫把你封杀了,所以一般来说开发爬虫要兼顾运维。所以爬虫的运维我可以提供下面几个思路:首先,从数据增量监控。定向爬虫(指的是只针对一个网站的爬虫)比较容易,一段时间之后对一些网站的数据增量会有一个大体的了解。经常看看这些数据的增加趋势是否是正常就可以了(Grafana)。非定向爬虫的数据增量不是很稳定,一般看机器的网络状况,网站的更新情况等(这方面我的经验不多)。然后看爬虫执行的成功情况。在上面提到了用任务队列控制爬虫工作,这样解耦可以带来很多好处,其中一个就是可以就是可以对一次爬虫执行进行日志。可以在每次爬虫任务执行的时候,将执行的时间、状态、目标url、异常等放入一个日志系统(比如kibana),然后通过一个可视化的手段可以清晰地看到爬虫的失败率。爬虫抛出的Exception。几乎所有的项目都会用到错误日志收集(Sentry),这里需要注意的一点是,忽略正常的异常(比如Connection错误,锁冲突等),否则的话你会被这些错误淹没。
如何安装和使用Beanstalkd工作队列
使用aptitude安装:
下载并安装Beanstalkd运行以下命令:
aptitude install -y beanstalkd
编辑默认配置文件让随着系统启动
vim /etc/default/beanstalkd
打开文件后,向下滚动并找到底部线#开始= yes。将其更改为:
START=yes
下面介绍源码安装
我们需要从源代码安装过程的一个关键工具- Git。
运行以下获取Git在你系统上:
aptitude install -y git
下载必要的开发工具软件包:
aptitude install -y build-essential
使用Git克隆(下载)官方库:
git clone
进入到下载目录:
cd beanstalkd
从源代码构建应用程序:
make
安装:
make install
再介绍一下centos下源码安装:
下载地址:
wget
解压:
tar xzf beanstalkd-1.4.6.tar.gz
cd beanstalkd-1.4.6
/configure
make
make install
默认安装路径 :/usr/local/bin/
查看版本:
/usr/local/bin/beanstalkd -v
1.4.6
再附加一个启动脚本,从Fedora下挖来的 startup 脚本:
#!/bin/sh
#
# beanstalkd – a simple, fast workqueue service
#
# chkconfig: – 57 47
# description: a simple, fast workqueue service
# processname: beanstalkd
# config: /etc/sysconfig/beanstalkd
#
### BEGIN INIT INFO
# Provides: beanstalkd
# Required-Start: $local_fs $network $remote_fs
# Required-Stop: $local_fs $network $remote_fs
# Default-Stop: 0 1 2 6
# Short-Description: start and stop beanstalkd
# Description: a simple, fast work-queue service
### END INIT INFO
# Source function library.
/etc/rc.d/init.d/functions
# Source networking configuration.
/etc/sysconfig/network
# Check that networking is up.
[ “$NETWORKING” = “no” ] exit
exec=”/usr/local/bin/beanstalkd”
prog=$(basename $exec)
# default options, overruled by items in sysconfig
BEANSTALKD_ADDR=127.0.0.1
BEANSTALKD_PORT=11300
BEANSTALKD_USER=beanstalkd
[ -e /etc/sysconfig/beanstalkd ] . /etc/sysconfig/beanstalkd
lockfile=/var/lock/subsys/beanstalkd
start() {
[ -x $exec ] || exit 5
echo -n $”Starting $prog: ”
# if not running, start it up here, usually something like “daemon $exec”
options=”-l ${BEANSTALKD_ADDR} -p ${BEANSTALKD_PORT} -u ${BEANSTALKD_USER}”
if [ “${BEANSTALKD_MAX_JOB_SIZE}” != “” ]; then
options=”${options} -z ${BEANSTALKD_MAX_JOB_SIZE}”
fi
if [ “${BEANSTALKD_BINLOG_DIR}” != “” ]; then
if [ ! -d “${BEANSTALKD_BINLOG_DIR}” ]; then
echo “Creating binlog directory (${BEANSTALKD_BINLOG_DIR})”
mkdir -p ${BEANSTALKD_BINLOG_DIR} chown ${BEANSTALKD_USER}:${BEANSTALKD_USER} ${BEANSTALKD_BINLOG_DIR}
fi
options=”${options} -b ${BEANSTALKD_BINLOG_DIR}”
if [ “${BEANSTALKD_BINLOG_FSYNC_PERIOD}” != “” ]; then
options=”${options} -f ${BEANSTALKD_BINLOG_FSYNC_PERIOD}”
else
options=”${options} -F”
fi
if [ “${BEANSTALKD_BINLOG_SIZE}” != “” ]; then
options=”${options} -s ${BEANSTALKD_BINLOG_SIZE}”
fi
fi
daemon $exec -d $options
retval=$?
echo
[ $retval -eq 0 ] touch $lockfile
return $retval
}
stop() {
echo -n $”Stopping $prog: ”
# stop it here, often “killproc $prog”
killproc $prog -INT
retval=$?
echo
[ $retval -eq 0 ] rm -f $lockfile
return $retval
}
restart() {
stop
start
}
reload() {
restart
}
force_reload() {
restart
}
rh_status() {
# run checks to determine if the service is running or use generic status
status $prog
}
rh_status_q() {
rh_status /dev/null 21
}
case “$1” in
start)
rh_status_q exit 0
$1
;;
stop)
rh_status_q || exit 0
$1
;;
restart)
$1
;;
reload)
rh_status_q || exit 7
$1
;;
force-reload)
force_reload
;;
status)
rh_status
;;
condrestart|try-restart)
rh_status_q || exit 0
restart
;;
*)
echo $”Usage: $0 {start|stop|status|restart|condrestart|try-restart|reload|force-reload}”
exit 2
esac
exit $?
使用Beanstalkd
在安装之后,您就可以开始使用Beanstalkd服务器。以下是运行守护进程的选项:
-b DIR wal directory
-f MS fsync at most once every MS milliseconds (use -f0 for “always fsync”)
-F never fsync (default)
-l ADDR listen on address (default is 0.0.0.0)
-p PORT listen on port (default is 11300)
-u USER become user and group
-z BYTES set the maximum job size in bytes (default is 65535)
-s BYTES set the size of each wal file (default is 10485760)
(will be rounded up to a multiple of 512 bytes)
-c compact the binlog (default)
-n do not compact the binlog
-v show version information
-V increase verbosity
-h show this help
使用例子:
# Usage: beanstalkd -l [ip address] -p [port #]
# For local only access:
beanstalkd -l 127.0.0.1 -p 11301
管理服务:
如果安装包管理器(i.e. aptitude),你将能够管理Beanstalkd作为服务守护进程。
# To start the service:
service beanstalkd start
# To stop the service:
service beanstalkd stop
# To restart the service:
service beanstalkd restart
# To check the status:
service beanstalkd status
获得Beanstalkd客户端库
Beanstalkd配有一长串的支持客户端库来处理许多不同的应用程序部署。这个列表的支持语言和框架,包括:
●Python
●Django
●Go
●Java
●Node.js
●Perl
●PHP
●Ruby
●and more.
查看完整列表支持,寻找你最喜欢的语言和安装说明,查看客户端库页面Beanstalkd Github上。
使用Beanstalkd
在本节之前,完成这篇文章,让我们快速Beanstalkd的基本用法。在我们的示例中,我们将使用Python语言和Beanstald Python bindings ——beanstalkc。
安装beanstalkc,运行以下命令:
pip install pyyaml
pip install beanstalkc
基本操作
在所有Python文件你想处理Beanstalkd时,需要导入beanstalkc并连接:
import beanstalkc
# Connection
beanstalk = beanstalkc.Connection(host=’www.easyaq.com’, port=11301)
To enqueue a job:
beanstalk.put(‘job_one’)
To receive a job:
job = beanstalk.reserve()
# job.body == ‘job_one’
To delete a job after processing it:
job.delete()
To use a specific tube (i.e. queue / list):
beanstalk.use(‘tube_a’)
To list all available tubes:
beanstalk.tubes()
# [‘default’, ‘tube_a’]
Final example (nano btc_ex.py):
import beanstalkc
# Connect
beanstalk = beanstalkc.Connection(host=’www.easyaq.com’, port=11301)
# See all tubes:
beanstalk.tubes()
# Switch to the default (tube):
beanstalk.use(‘default’)
# To enqueue a job:
beanstalk.put(‘job_one’)
# To receive a job:
job = beanstalk.reserve()
# Work with the job:
print job.body
# Delete the job:
job.delete()
当您运行上面的脚本时,您应该会看到工作的主体被打印:
python btc_ex.py
# job_one