最全Python爬虫总结

最近总是要爬取一些东西,索性就把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(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会自动的去抓取这些链接

时间: 2024-10-05 12:59:45

最全Python爬虫总结的相关文章

最全Python爬虫总结(转载)

[html] view plain copy 最近总是要爬取一些东西,索性就把Python爬虫的相关内容都总结起来了,自己多动手还是好. (1)普通的内容爬取(2)保存爬取的图片/视频和文件和网页(3)普通模拟登录(4)处理验证码登录(5)爬取js网站(6)全网爬虫(7)某个网站的站内所有目录爬虫(8)多线程 (9)爬虫框架Scrapy 一,普通的内容爬取 [html] view plain copy #coding=utf-8 import urllib import urllib2 url 

史上最最最最最最最最全Python爬虫总结

(1)普通的内容爬取(2)保存爬取的图片/视频和文件和网页(3)普通模拟登录(4)处理验证码登录(5)爬取js网站(6)全网爬虫(7)某个网站的站内所有目录爬虫(8)多线程 (9)爬虫框架Scrapy 一,普通的内容爬取 1 #coding=utf-8 2 #Python学习交流群:548377875 3 import urllib 4 import urllib2 5 url = 'http://www.dataanswer.top' 6 headers = { 7 'Host':'www.d

Python爬虫利器六之PyQuery的用法

前言 你是否觉得 XPath 的用法多少有点晦涩难记呢? 你是否觉得 BeautifulSoup 的语法多少有些悭吝难懂呢? 你是否甚至还在苦苦研究正则表达式却因为少些了一个点而抓狂呢? 你是否已经有了一些前端基础了解选择器却与另外一些奇怪的选择器语法混淆了呢? 嗯,那么,前端大大们的福音来了,PyQuery 来了,乍听名字,你一定联想到了 jQuery,如果你对 jQuery 熟悉,那么 PyQuery 来解析文档就是不二之选!包括我在内! PyQuery 是 Python 仿照 jQuery

Python爬虫入门七之正则表达式

在前面我们已经搞定了怎样获取页面的内容,不过还差一步,这么多杂乱的代码夹杂文字我们怎样把它提取出来整理呢?下面就开始介绍一个十分强大的工具,正则表达式! 1.了解正则表达式 正则表达式是对字符串操作的一种逻辑公式,就是用事先定义好的一些特定字符.及这些特定字符的组合,组成一个"规则字符串",这个"规则字符串"用来表达对字符串的一种过滤逻辑. 正则表达式是用来匹配字符串非常强大的工具,在其他编程语言中同样有正则表达式的概念,Python同样不例外,利用了正则表达式,我

转 Python爬虫入门七之正则表达式

静觅 » Python爬虫入门七之正则表达式 1.了解正则表达式 正则表达式是对字符串操作的一种逻辑公式,就是用事先定义好的一些特定字符.及这些特定字符的组合,组成一个“规则字符串”,这个“规则字符串”用来表达对字符串的一种过滤逻辑. 正则表达式是用来匹配字符串非常强大的工具,在其他编程语言中同样有正则表达式的概念,Python同样不例外,利用了正则表达式,我们想要从返回的页面内容提取出我们想要的内容就易如反掌了. 正则表达式的大致匹配过程是:1.依次拿出表达式和文本中的字符比较,2.如果每一个

Python爬虫的Urllib库有哪些高级用法?

本文和大家分享的主要是python爬虫的Urllib库的高级用法相关内容,一起来看看吧,希望对大家学习python有所帮助. 1.分分钟扒一个网页下来 怎样扒网页呢?其实就是根据URL来获取它的网页信息,虽然我们在浏览器中看到的是一幅幅优美的画面,但是其实是由浏览器解释才呈现出来的,实质它 是一段HTML代码,加 JS.CSS,如果把网页比作一个人,那么HTML便是他的骨架,JS便是他的肌肉,CSS便是它的衣服.所以最重要的部分是存在于HTML中的,下面我 们就写个例子来扒一个网页下来. imp

Python实战:Python爬虫学习教程,获取电影排行榜

Python应用现在如火如荼,应用范围很广.因其效率高开发迅速的优势,快速进入编程语言排行榜前几名.本系列文章致力于可以全面系统的介绍Python语言开发知识和相关知识总结.希望大家能够快速入门并学习Python这门语言. 本文是在前一部分Python基础之上程序员带你十天快速入门Python,玩转电脑软件开发(四),再次进行的Python爬虫实战课程. 正则表达式实例简单详解 正则表达式干什么用? 就是在字符串中提取我们需要的内容的. 记得哦,要先引用正则表达式模块的哦. re就是正则表达式相

python爬虫实战——5分钟做个图片自动下载器

python爬虫实战--图片自动下载器 制作爬虫的基本步骤 顺便通过这个小例子,可以掌握一些有关制作爬虫的基本的步骤. 一般来说,制作一个爬虫需要分以下几个步骤: 分析需求(对,需求分析非常重要,不要告诉我你老师没教你) 分析网页源代码,配合F12(没有F12那么乱的网页源代码,你想看死我?) 编写正则表达式或者XPath表达式(就是前面说的那个神器) 正式编写python爬虫代码 效果 运行: 恩,让我输入关键词,让我想想,输入什么好呢?好像有点暴露爱好了. 回车 好像开始下载了!好赞!,我看

【图文详解】python爬虫实战——5分钟做个图片自动下载器

python爬虫实战--图片自动下载器 之前介绍了那么多基本知识[Python爬虫]入门知识,大家也估计手痒了.想要实际做个小东西来看看,毕竟: talk is cheap show me the code! 制作爬虫的基本步骤 顺便通过这个小例子,可以掌握一些有关制作爬虫的基本的步骤. 一般来说,制作一个爬虫需要分以下几个步骤: 1. 分析需求(对,需求分析非常重要,不要告诉我你老师没教你) 2. 分析网页源代码,配合F12(没有F12那么乱的网页源代码,你想看死我?) 3. 编写正则表达式或