首先要掌握一些有关爬虫的基础知识,基本的要知道什么是爬虫?为什么要爬虫?数据是从哪里得来的?先了解这些基础的知识点才能对你要学习的东西有基本的了解,然后还有下面这些数据也需要了解:
1、HTML,了解网页的结构,内容等,帮助后续的数据爬取。
2、Python,可以去网上找一些教学视频,教学博客等等,去看一下,然后有基础了之后还可以找一些晋升的视频,再打打基础。
3、TCP/IP协议,HTTP协议,了解在网络请求和网络传输上的基本原理,帮助今后写爬虫的时候理解爬虫的逻辑。
好了言归正传:
一、爬虫概述
爬虫,即网络爬虫,通过递归访问网络资源,抓取信息。
比如它在抓取一个网页,在这个网中他发现了一条道路,其实就是指向网页的超链接,那么它就可以爬到另一张网上来获取数据。这样,整个连在一起的大网对这之蜘蛛来说触手可及,理论上可以将爬取到整个互联网的绝大部分数据。
二、python基础爬虫之Urllib库
1.入门案例
案例1:访问url读取返回结果
import urllib2
response = urllib2.urlopen("http://www.baidu.com")
print response.read()
说明:
urlopen(url, data, timeout)
第一个参数url即为URL,第二个参数data是访问URL时要传送的数据,第三个timeout是设置超时时间。
第二三个参数是可以不传送的,data默认为空None,timeout默认为 socket._GLOBAL_DEFAULT_TIMEOUT
第一个参数URL是必须要传送的,在这个例子里面我们传送了百度的URL,执行urlopen方法之后,返回一个response对象,返回信息便保存在这里面
案例2:构造request访问url读取返回结果
import urllib2
request = urllib2.Request("http://www.baidu.com")
response = urllib2.urlopen(request)
print response.read()
运行结果是完全一样的,只不过中间多了一个request对象,更加面向对象
案例3:Get提交
import urllib
import urllib2
values={'username':'park','password'='123'}
data = urllib.urlencode(values)
url = "http://www.baidu.com" + "?"+data
request = urllib2.Request(url)
response = urllib2.urlopen(request)
print response.read()
案例4:Post提交
import urllib
import urllib2
values = {"username":"park","password":"123"}
data = urllib.urlencode(values)
url = "https://www.baidu.com"
request = urllib2.Request(url,data)
response = urllib2.urlopen(request)
print response.read()
案例5:设置Headers
有些网站不会同意程序直接用上面的方式进行访问,如果识别有问题,那么站点根本不会响应,所以为了完全模拟浏览器的工作,我们需要设置一些Headers 的属性。
import urllib
import urllib2
url = 'http://www.xxxx.com/xxx'
values = {'username' : 'pq', 'password' : 'xxx' }
headers = { 'User-Agent' : 'Mozilla/4.0 (compatible; MSIE 5.5; Windows NT)' ,
'Referer':'http://www.baidu.com/' }
data = urllib.urlencode(values)
request = urllib2.Request(url, data, headers)
response = urllib2.urlopen(request)
page = response.read()
案例6:代理设置
urllib2 默认会使用环境变量 http_proxy 来设置 HTTP Proxy。
假如一个网站它会检测某一段时间某个IP 的访问次数,如果访问次数过多,它会禁止你的访问。
所以你可以设置一些代理服务器来帮助你做工作,每隔一段时间换一个代理,以此绕过ip检测。
import urllib2
enable_proxy = True
proxy_handler = urllib2.ProxyHandler({"http" : 'http://some-proxy.com:8080'})
null_proxy_handler = urllib2.ProxyHandler({})
if enable_proxy:
opener = urllib2.build_opener(proxy_handler)
else:
opener = urllib2.build_opener(null_proxy_handler)
urllib2.install_opener(opener)
案例7:超时时间设置
import urllib2
response = urllib2.urlopen('http://www.baidu.com', timeout=10)
或
import urllib2
response = urllib2.urlopen('http://www.baidu.com',data, 10)
案例8:使用DebugLog
可以通过下面的方法把 Debug Log 打开,这样收发包的内容就会在屏幕上打印出来,方便调试
import urllib2
httpHandler = urllib2.HTTPHandler(debuglevel=1)
httpsHandler = urllib2.HTTPSHandler(debuglevel=1)
opener = urllib2.build_opener(httpHandler, httpsHandler)
urllib2.install_opener(opener)
response = urllib2.urlopen('http://www.baidu.com')
案例9:使用cookie
当你获取一个URL你使用一个opener(一个urllib2.OpenerDirector的实例)。在前面,我们都是使用的默认的opener,也就是urlopen。它是一个特殊的opener,可以理解成opener的一个特殊实例,传入的参数仅仅是url,data,timeout。
如果我们需要用到Cookie,只用这个opener是不能达到目的的,所以我们需要创建更一般的opener来实现对Cookie的设置。
import cookielib
import urllib2
#设置保存cookie的文件,同级目录下的cookie.txt
filename = 'cookie.txt'
#声明一个MozillaCookieJar对象实例来保存cookie,之后写入文件
cookie = cookielib.MozillaCookieJar(filename)
#利用urllib2库的HTTPCookieProcessor对象来创建cookie处理器
handler = urllib2.HTTPCookieProcessor(cookie)
#通过handler来构建opener
opener = urllib2.build_opener(handler)
#创建一个请求,原理同urllib2的urlopen
response = opener.open("http://www.baidu.com")
#保存cookie到文件
#ignore_discard的意思是即使cookies将被丢弃也将它保存下来,ignore_expires的意思是如果在该文件中cookies已经存在,则覆盖原文件写入,在这里,我们将这两个全部设置为True。
cookie.save(ignore_discard=True, ignore_expires=True)
import cookielib
import urllib2
#创建MozillaCookieJar实例对象
cookie = cookielib.MozillaCookieJar()
#从文件中读取cookie内容到变量
cookie.load('cookie.txt', ignore_discard=True, ignore_expires=True)
#创建请求的request
req = urllib2.Request("http://www.baidu.com")
#利用urllib2的build_opener方法创建一个opener
opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cookie))
response = opener.open(req)
print response.read()
三、Python爬虫框架
基于Python的爬虫框架有很多,比较知名的是Scrapy 和PySpider。
pyspider上手更简单,操作更加简便,因为它增加了 WEB 界面,写爬虫迅速,集成了phantomjs,可以用来抓取js渲染的页面。
Scrapy自定义程度高,比 PySpider更底层一些,适合学习研究,需要学习的相关知识多,不过自己拿来研究分布式和多线程等等是非常合适的。
我们主要介绍pyspider
1.pyspider安装配置
(1)安装pip
pip是python的包管理工具 类似RedHat里面的yum
访问https://pypi.python.org/pypi/pip#downloads
下载pip安装包
解压pip-9.0.1.tar.gz
在该目录下执行 setup.py install
将python安装目录下的Scripts配置到PATH环境变量
(2)安装phantomjs
访问http://phantomjs.org/download.html
下载对应版本phantomjs
解压phantomjs-2.1.1-windows.zip
将其bin目录配置到PATH环境变量中
(3)使用pip安装pyspider
pip install pyspider
(4)运行pyspider
pyspider all
(5)通过浏览器访问pyspider
http://localhost:5000
2.PySpider语法
http://docs.pyspider.org/en/latest/
略
3.PySpider案例
http://cuiqingcai.com/2652.html
#!/usr/bin/env python
# -*- encoding: utf-8 -*-
# Created on 2018-11-17 10:28:34
# Project: MM_TT
from pyspider.libs.base_handler import *
import os
import random
class Handler(BaseHandler):
crawl_config = {
}
baseDir = 'E:\\tbmm';
def __init__(self):
pass
@every(minutes=24 * 60)
def on_start(self):
for x in range(30):
self.crawl('https://mm.taobao.com/json/request_top_list.htm?page='+str(x+1), callback=self.index_page,validate_cert=False)
@config(age=10 * 24 * 60 * 60)
def index_page(self, response):
for each in response.doc('.lady-name').items():
self.crawl(each.attr.href,callback=self.mm_page,validate_cert=False,fetch_type='js')
@config(age=10 * 24 * 60 * 60)
def mm_page(self, response):
self.crawl("https:"+response.doc('.mm-p-domain-info li > span').text(),callback=self.mm_detail_page,validate_cert=False,fetch_type='js')
@config(age=10 * 24 * 60 * 60)
def mm_detail_page(self, response):
#获取mm名字 创建对应文件夹
mm_name = response.doc('.mm-p-model-info-left-top dd>a').text().encode("gbk")
if not os.path.exists(self.baseDir+'\\'+mm_name):
os.mkdir(self.baseDir+'\\'+mm_name)
#创建desc.txt写出描述信息
mm_desc = response.doc('.mm-aixiu-content').text().encode("gbk")
f = open(self.baseDir+'\\'+mm_name+"\\desc.txt",'w')
f.write(mm_desc)
f.flush()
f.close()
#获取mm所有图片地址 加入爬取
mm_imgs = response.doc('.mm-aixiu-content > div > img').items()
for mm_img in mm_imgs:
self.crawl(mm_img.attr.src, callback=self.download_img_page,validate_cert=False,save={'imgdir':self.baseDir+'\\'+mm_name+'\\'+mm_img.attr.src.split("/")[-1]})
@config(age=10 * 24 * 60 * 60)
def download_img_page(self, response):
imgcontent=response.content
imgfile=open(response.save['imgdir'],"wb")
imgfile.write(imgcontent)
imgfile.flush()
imgfile.close()