最全Python爬虫总结(转载)
[html] view plain copy
- 最近总是要爬取一些东西,索性就把Python爬虫的相关内容都总结起来了,自己多动手还是好。
(1)普通的内容爬取
(2)保存爬取的图片/视频和文件和网页
(3)普通模拟登录
(4)处理验证码登录
(5)爬取js网站
(6)全网爬虫
(7)某个网站的站内所有目录爬虫
(8)多线程
(9)爬虫框架Scrapy
一,普通的内容爬取
- #coding=utf-8
- import urllib
- import urllib2
- url = 'http://www.dataanswer.top'
- headers = {
- 'Host':'www.dataanswer.top',
- 'User-Agent':'Mozilla/5.0 (X11; Ubuntu; Linux i686; rv:31.0) Gecko/20100101 Firefox/31.0',
- #'Accept':'application/json, text/javascript, */*; q=0.01',
- #'Accept-Language':'zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3',
- #'Accept-Encoding':'gzip,deflate',
- #'Referer':'http://www.dataanswer.top'
- }
- request = urllib2.Request(url,headers=headers)
- response = urllib2.urlopen(request)
- page = response.read()
- print page
二,保存爬取的图片/视频和文件和网页
#图片/视频和文件和网页的地址抓取下来后,利用模块urllib里的urlretrieve()方法下载下来:
- #coding=utf-8
- import urllib
- import urllib2
- import os
- def getPage(url):
- request = urllib2.Request(url)
- response = urllib2.urlopen(request)
- return response.read()
- url='http://www.dataanswer.top/'
- result=getPage(url)
- file_name='test.doc'
- file_path='doc'
- if os.path.exists(file_path) == False:
- os.makedirs(file_path)
- local=os.path.join(file_path,file_name)
- f = open(local,"w+")
- f.write(result)
- f.close()
- #coding=utf-8
- import urllib
- import urllib2
- import os
- def getPage(url):
- request = urllib2.Request(url)
- response = urllib2.urlopen(request)
- return response.read()
- url='http://www.dataanswer.top/' #把该地址改成图片/文件/视频/网页的地址即可
- result=getPage(url)
- file_name='test.doc'
- file_path='doc'
- if os.path.exists(file_path) == False:
- os.makedirs(file_path)
- local=os.path.join(file_path,file_name)
- urllib.urlretrieve(url,local)
三,普通模拟登录
- import urllib
- import urllib2
- import cookielib
- filename = 'cookie.txt'
- #声明一个MozillaCookieJar对象实例来保存cookie,之后写入文件
- cookie = cookielib.MozillaCookieJar(filename)
- opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cookie))
- postdata = urllib.urlencode({
- 'name':'春天里',
- 'pwd':'1222222'
- })
- #登录的URL
- loginUrl = 'http://www.dataanswer.top/LoginService?action=tologin'
- #模拟登录,并把cookie保存到变量
- result = opener.open(loginUrl,postdata)
- #保存cookie到cookie.txt中
- cookie.save(ignore_discard=True, ignore_expires=True)
- #利用cookie请求访问另一个网址
- gradeUrl = 'http://www.dataanswer.top/LoginService?action=myHome'
- #请求访问
- result = opener.open(gradeUrl)
- print result.read()
四,处理验证码登录
#先把验证码图片下载下来保存,再人工读入
- #coding=utf-8
- import sys, time, os, re
- import urllib, urllib2, cookielib
- loginurl = 'https://www.douban.com/accounts/login'
- cookie = cookielib.CookieJar()
- opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cookie))
- params = {
- "form_email":"13161055481",
- "form_password":"wwwwwww",
- "source":"index_nav" #没有的话登录不成功
- }
- #从首页提交登录
- response=opener.open(loginurl)
- #验证成功跳转至登录页
- print(response.geturl())
- if response.geturl() == "https://www.douban.com/accounts/login":
- html=response.read()
- print(html)
- #验证码图片地址--图片地址加密怎么办???
- imgurl=re.search('<img id="captcha_image" src="(.+?)" alt="captcha" class="captcha_image"/>', html)
- print(imgurl)
- if imgurl:
- url=imgurl.group(1)
- #将图片保存至同目录下
- res=urllib.urlretrieve(url,'v.jpg')
- #获取captcha-id参数
- captcha=re.search('<input type="hidden" name="captcha-id" value="(.+?)"/>',html)
- if captcha:
- vcode=raw_input('请输入图片上的验证码:')
- params["captcha-solution"]=vcode
- params["captcha-id"]=captcha.group(1)
- params["user_login"]="登录"
- #提交验证码验证
- response=opener.open(loginurl, urllib.urlencode(params))
- ''' 登录成功跳转至首页 '''
- if response.geturl() == "https://www.douban.com/":
- print 'login success ! '
- print '准备进行发帖'
- addtopicurl="http://www.douban.com/group/python/new_topic"
- res=opener.open(addtopicurl)
- html=res.read()
- else:
- print("Fail3")
- else:
- print("Fail2")
- else:
- print("Fail1")
- else:
- print("Fail0")
五,爬取js网站
#利用selenium模拟浏览器,结合html的解析
- #coding=utf-8
- #1、安装 python-pip
- #sudo apt-get install python-pip
- #2、安装selenium
- #sudo pip install -U selenium
- from selenium import webdriver
- driver = webdriver.Firefox()
- driver.get('http://www.newsmth.net/nForum/#!article/Intern/206790')
- html=driver.page_source.encode('utf-8','ignore') #这个函数获取页面的html
- print(html)
- driver.close()
六,全网爬虫
#广度优先,模拟爬取队列
- #coding=utf-8
- """
- 全网爬取所有链接,包括外链--广度优先
- """
- import urllib2
- import re
- from bs4 import BeautifulSoup
- import time
- #爬虫开始的时间
- t=time.time()
- #设置的暂停爬取条数
- N_STOP=10
- #存放已经爬取过的url
- CHECKED_URL=[]
- #存放待爬取的url
- CHECKING_URL=[]
- #存放连接失败的url
- FAIL_URL=[]
- #存放不能连接的url
- ERROR_URL=[]
- #失败后允许连接的次数
- RETRY=3
- #连接超时时间
- TIMEOUT=20
- class url_node:
- def __init__(self,url):
- """
- url节点初始化
- :param url:String 当前url
- """
- self.url=url
- self.content=''
- def __is_connectable(self):
- """
- 检验url是否可以连接
- """
- #在允许连接次数下连接
- for i in range(RETRY):
- try:
- #打开url没有报错,则表示可连接
- response=urllib2.urlopen(self.url,timeout=TIMEOUT)
- return True
- except:
- #如果在尝试允许连接次数下报错,则不可连接
- if i==RETRY-1:
- return False
- def get_next(self):
- """
- 获取爬取该页中包含的其他所有的url
- """
- soup=BeautifulSoup(self.content)
- #******************在此处可以从网页中解析你想要的内容************************************
- next_urls=soup.findAll('a')
- if len(next_urls)!=0:
- for link in next_urls:
- tmp_url=link.get('href')
- #如果url不在爬取过的列表中也不在待爬取列表中则把其放到待爬列表中(没有确保该url有效)
- if tmp_url not in CHECKED_URL and tmp_url not in CHECKING_URL:
- CHECKING_URL.append(tmp_url)
- def run(self):
- if self.url:
- if self.__is_connectable():
- try:
- #获取爬取页面的所有内容
- self.content=urllib2.urlopen(self.url,timeout=TIMEOUT).read()
- #从该页面中获取url
- self.get_next()
- except:
- #把连接失败的存放起来
- FAIL_URL.append(self.url)
- print('[!]Connect Failed')
- else:
- #把不能连接的存放起来
- ERROR_URL.append(self.url)
- else:
- print("所给的初始url有问题!")
- if __name__=='__main__':
- #把初始的url放到待爬的列表中
- CHECKING_URL.append('http://www.36dsj.com/')
- #不断的从待爬的列表中获取url进行爬取
- ff=open("Mytest.txt",'w')
- i=0
- for url in CHECKING_URL:
- #对该url进行爬取
- url_node(url).run()
- #存放已经爬取过的url
- CHECKED_URL.append(url)
- #删除CHECKING_URL中已经爬取过的url
- CHECKING_URL.remove(url)
- i+=1
- if i==N_STOP:
- #打出停止时的url,下次可以把该url作为初始继续
- print url
- print("爬取过的列表长度:%d") % len(CHECKED_URL)
- print("待爬取的列表长度:%d") % len(CHECKING_URL)
- print("连接失败的列表长度:%d") % len(FAIL_URL)
- print("不能连接的列表长度:%d") % len(ERROR_URL)
- break
- ff.close()
- print("time:%d s") % (time.time()-t)
七,某个网站的站内所有目录爬虫
#把缩写的站内网址还原
- #coding=utf-8
- """
- 爬取同一个网站所有的url,不包括外链
- """
- import urllib2
- import re
- from bs4 import BeautifulSoup
- import time
- t=time.time()
- HOST=''
- CHECKED_URL=[]
- CHECKING_URL=[]
- RESULT=[]
- RETRY=3
- TIMEOUT=20
- class url_node:
- def __init__(self,url):
- """
- url节点初始化
- :param url:String 当前url
- """
- self.url=self.handle_url(url,is_next_url=False)
- self.next_url=[]
- self.content=''
- def handle_url(self,url,is_next_url=True):
- """
- 将所有的url处理成标准形式
- """
- global CHECKED_URL
- global CHECKING_URL
- #去掉尾部的‘/’
- url=url[0:len(url)-1] if url.endswith('/') else url
- if url.find(HOST)==-1:
- if not url.startswith('http'):
- url='http://'+HOST+url if url.startswith('/') else 'http://'+HOST+'/'+url
- else:
- #如果含有http说明是外链,url的host不是当前的host,返回空
- return
- else:
- if not url.startswith('http'):
- url='http://'+url
- if is_next_url:
- #下一层url放入待检测列表
- if url not in CHECKING_URL:
- CHECKING_URL.append(url)
- else:
- #对于当前需要检测的url将参数都替换为1,然后加入规则表
- #参数相同类型不同的url只检测一次
- rule=re.compile(r'=.*?\&|=.*?$')
- result=re.sub(rule,'=1&',url)
- if result in CHECKED_URL:
- return '[!] Url has checked!'
- else:
- CHECKED_URL.append(result)
- RESULT.append(url)
- return url
- def __is_connectable(self):
- print("进入__is_connectable()函数")
- #检验是否可以连接
- retry=3
- timeout=2
- for i in range(RETRY):
- try:
- #print("进入_..............函数")
- response=urllib2.urlopen(self.url,timeout=TIMEOUT)
- return True
- except:
- if i==retry-1:
- return False
- def get_next(self):
- #获取当前所有的url
- #print("进入get_next()函数")
- soup=BeautifulSoup(self.content)
- next_urls=soup.findAll('a')
- if len(next_urls)!=0:
- for link in next_urls:
- self.handle_url(link.get('href'))
- #print(link.text)
- def run(self):
- #print("进入run()函数")
- if self.url:
- #print self.url
- if self.__is_connectable():
- try:
- self.content=urllib2.urlopen(self.url,timeout=TIMEOUT).read()
- self.get_next()
- except:
- print('[!]Connect Failed')
- #处理https开头的url的类和方法
- class Poc:
- def run(self,url):
- global HOST
- global CHECKING_URL
- url=check_url(url)
- if not url.find('https'):
- HOST=url[:8]
- else:
- HOST=url[7:]
- for url in CHECKING_URL:
- print(url)
- url_node(url).run()
- def check_url(url):
- url='http://'+url if not url.startswith('http') else url
- url=url[0:len(url)-1] if url.endswith('/') else url
- for i in range(RETRY):
- try:
- response=urllib2.urlopen(url,timeout=TIMEOUT)
- return url
- except:
- raise Exception("Connect error")
- if __name__=='__main__':
- HOST='www.dataanswer.com'
- CHECKING_URL.append('http://www.dataanswer.com/')
- f=open('36大数据','w')
- for url in CHECKING_URL:
- f.write(url+'\n')
- print(url)
- url_node(url).run()
- print RESULT
- print "URL num:"+str(len(RESULT))
- print("time:%d s") % (time.time()-t)
八,多线程
#对列和线程的结合
- #!/usr/bin/env python
- # -*- coding:utf-8 -*-
- """
- 一个简单的Python爬虫, 使用了多线程,
- 爬取豆瓣Top前250的所有电影
- """
- import urllib2, re, string
- import threading, Queue, time
- import sys
- reload(sys)
- sys.setdefaultencoding('utf8')
- _DATA = []
- FILE_LOCK = threading.Lock()
- SHARE_Q = Queue.Queue() #构造一个不限制大小的的队列
- _WORKER_THREAD_NUM = 3 #设置线程的个数
- class MyThread(threading.Thread) :
- def __init__(self, func) :
- super(MyThread, self).__init__() #调用父类的构造函数
- self.func = func #传入线程函数逻辑
- def run(self) :
- self.func()
- def worker() :
- global SHARE_Q
- while not SHARE_Q.empty():
- url = SHARE_Q.get() #获得任务
- my_page = get_page(url)
- find_title(my_page) #获得当前页面的电影名
- #write_into_file(temp_data)
- time.sleep(1)
- SHARE_Q.task_done()
- def get_page(url) :
- """
- 根据所给的url爬取网页HTML
- Args:
- url: 表示当前要爬取页面的url
- Returns:
- 返回抓取到整个页面的HTML(unicode编码)
- Raises:
- URLError:url引发的异常
- """
- try :
- my_page = urllib2.urlopen(url).read().decode("utf-8")
- except urllib2.URLError, e :
- if hasattr(e, "code"):
- print "The server couldn't fulfill the request."
- print "Error code: %s" % e.code
- elif hasattr(e, "reason"):
- print "We failed to reach a server. Please check your url and read the Reason"
- print "Reason: %s" % e.reason
- return my_page
- def find_title(my_page) :
- """
- 通过返回的整个网页HTML, 正则匹配前100的电影名称
- Args:
- my_page: 传入页面的HTML文本用于正则匹配
- """
- temp_data = []
- movie_items = re.findall(r'<span.*?class="title">(.*?)</span>', my_page, re.S)
- for index, item in enumerate(movie_items) :
- if item.find(" ") == -1 :
- #print item,
- temp_data.append(item)
- _DATA.append(temp_data)
- def main() :
- global SHARE_Q
- threads = []
- douban_url = "http://movie.douban.com/top250?start={page}&filter=&type="
- #向队列中放入任务, 真正使用时, 应该设置为可持续的放入任务
- for index in xrange(10) :
- SHARE_Q.put(douban_url.format(page = index * 25))
- for i in xrange(_WORKER_THREAD_NUM) :
- thread = MyThread(worker)
- thread.start() #线程开始处理任务
- print("第%s个线程开始工作") % i
- threads.append(thread)
- for thread in threads :
- thread.join()
- SHARE_Q.join()
- with open("movie.txt", "w+") as my_file :
- for page in _DATA :
- for movie_name in page:
- my_file.write(movie_name + "\n")
- print "Spider Successful!!!"
- if __name__ == '__main__':
- main()
九,爬虫框架Scrapy
items.py:用来定义需要保存的变量,其中的变量用Field来定义,有点像python的字典
pipelines.py:用来将提取出来的Item进行处理,处理过程按自己需要进行定义
spiders:定义自己的爬虫
爬虫的类型也有好几种:
1)spider:最基本的爬虫,其他的爬虫一般是继承了该最基本的爬虫类,提供访问url,返回response的功能,会默认调用parse方法
2)CrawlSpider:继承spider的爬虫,实际使用比较多,设定rule规则进行网页的跟进与处理, 注意点:编写爬虫的规则的时候避免使用parse名,因为这会覆盖继承的spider的的方法parse造成错误。 其中比较重要的是对Rule的规则的编写,要对具体的网页的情况进行分析。
3)XMLFeedSpider 与 CSVFeedSpider
(1)打开命令行,执行:scrapy startproject tutorial(项目名称)
(2)scrapy.cfg是项目的配置文件,用户自己写的spider要放在spiders目录下面
(3)解析:name属性很重要,不同spider不能使用相同的name
start_urls是spider抓取网页的起始点,可以包括多个url
parse方法是spider抓到一个网页以后默认调用的callback,避免使用这个名字来定义自己的方法。
当spider拿到url的内容以后,会调用parse方法,并且传递一个response参数给它,response包含了抓到的网页的内容,在parse方法里,你可以从抓到的网页里面解析数据。
(3)开始抓取,进入生成的项目根目录tutorial/,执行 scrapy crawl dmoz, dmoz是spider的name。
(4)保存对象:在items.py中添加一些类,这些类用来描述我们要保存的数据
from scrapy.item import Item, Field
class DmozItem(Item):
title = Field()
link = Field()
desc = Field()
(5)执行scrapy crawl dmoz --set FEED_URI=items.json --set FEED_FORMAT=json后得到保存的文件
(6)让scrapy自动抓取网页上的所有链接
在parse方法里面提取我们需要的链接,然后构造一些Request对象,并且把他们返回,scrapy会自动的去抓取这些链接
最全Python爬虫总结(转载)的更多相关文章
- 如何利用python爬虫爬取爱奇艺VIP电影?
环境:windows python3.7 思路: 1.先选取你要爬取的电影 2.用vip解析工具解析,获取地址 3.写好脚本,下载片断 4.将片断利用电脑合成 需要的python模块: ##第一 ...
- [python爬虫] Selenium常见元素定位方法和操作的学习介绍(转载)
转载地址:[python爬虫] Selenium常见元素定位方法和操作的学习介绍 一. 定位元素方法 官网地址:http://selenium-python.readthedocs.org/locat ...
- 转载:用python爬虫抓站的一些技巧总结
原文链接:http://www.pythonclub.org/python-network-application/observer-spider 原文的名称虽然用了<用python爬虫抓站的一 ...
- 非常全的一份Python爬虫的Xpath博文
非常全的一份Python爬虫的Xpath博文 Xpath 是 python 爬虫过程中非常重要的一个用来定位的一种语法. 一.开始使用 首先我们需要得到一个 HTML 源代码,用来模拟爬取网页中的源代 ...
- 【转载】教你分分钟学会用python爬虫框架Scrapy爬取心目中的女神
原文:教你分分钟学会用python爬虫框架Scrapy爬取心目中的女神 本博文将带领你从入门到精通爬虫框架Scrapy,最终具备爬取任何网页的数据的能力.本文以校花网为例进行爬取,校花网:http:/ ...
- Python爬虫入门之正则表达式
在前面我们已经搞定了怎样获取页面的内容,不过还差一步,这么多杂乱的代码夹杂文字我们怎样把它提取出来整理呢?下面就开始介绍一个十分强大的工具,正则表达式! 1.了解正则表达式 正则表达式是对字符串操作的 ...
- Python爬虫入门之Urllib库的高级用法
1.设置Headers 有些网站不会同意程序直接用上面的方式进行访问,如果识别有问题,那么站点根本不会响应,所以为了完全模拟浏览器的工作,我们需要设置一些Headers 的属性. 首先,打开我们的浏览 ...
- Python爬虫入门之Urllib库的基本使用
那么接下来,小伙伴们就一起和我真正迈向我们的爬虫之路吧. 1.分分钟扒一个网页下来 怎样扒网页呢?其实就是根据URL来获取它的网页信息,虽然我们在浏览器中看到的是一幅幅优美的画面,但是其实是由浏览器解 ...
- 3.Python爬虫入门三之Urllib和Urllib2库的基本使用
1.分分钟扒一个网页下来 怎样扒网页呢?其实就是根据URL来获取它的网页信息,虽然我们在浏览器中看到的是一幅幅优美的画面,但是其实是由浏览器解释才呈现出来的,实质它是一段HTML代码,加 JS.CSS ...
随机推荐
- [C++]线性链表之顺序表<二>
/* @content 线性链表之顺序表 @date 2017-3-21 1:06 @author Johnny Zen */ /* 线性表 顺序表 链式表[带头指针/不 ...
- POJ3304 Segments 【线段直线相交】
题意: 给出n条线段两个端点的坐标,问所有线段投影到一条直线上,如果这些所有投影至少相交于一点就输出Yes!,否则输出No!. 思路: 计算几何.这道题要思考到两点: 1:把问题转化为是否存在一条直线 ...
- ubuntu16.04+anaconda的安装+解决conda不可用(配置路径)+卸载
首先一点,之前我一直自己安装python,然后直接在python环境下再安装第三方库,但自从另一台电脑重装系统之后,我当时在没有python的情况下直接安装的anaconda,觉得她超级好用(所以如果 ...
- zabbix实现对tomcat的监控
zabbix实现对tomcat的监控 工作原理 比如:当Zabbix-Server需要知道java应用程序的某项性能的时候,会启动自身的一个Zabbix-JavaPollers进程去连接Zabbix- ...
- 内存分配方式,堆区,栈区,new/delete/malloc/free
1.内存分配方式 内存分配方式有三种: [1]从静态存储区域分配.内存在程序编译的时候就已经分配好,这块内存在程序的整个运行期间都存在.例如全局变量,static变量. [2]在栈上创建.在执行函数时 ...
- JavaScript的类型自动转换高级玩法JSFuck
0 前言 最开始是不小心在微信公众号(程序员大咖)看到一篇JS的高逼格代码,然后通过里面的链接跳转到了JSFuck的wiki,就像顺着迷宫找宝藏的感觉,感叹JS的自动类型转换的牛逼. 1 样例 (!( ...
- Go语言规格说明书 之 通道 发送语句(send) 和 接收操作符(receive)
go version go1.11 windows/amd64 本文为阅读Go语言中文官网的规则说明书(https://golang.google.cn/ref/spec)而做的笔记,介绍Go语言的 ...
- vue系列之Vue-cli
Vue-cli是Vue的脚手架工具 vue-cli 地址:https://github.com/vuejs/vue-cli 安装 npm install -g vue-cli 使用 vue init ...
- javaMelody监控javaWeb程序性能
JavaMelody应用监控使用指南 原文:<JavaMelody应用监控使用指南> 前言 本文参考JavaMelody的UserGuide编写,部分文字均来自文档,添加有个人理解.并进行 ...
- WPS for Linux
https://www.cnblogs.com/gisalameda/p/6839482.html