爬虫常用的三种通用模板小结

news/2024/7/19 9:32:38 标签: python, 爬虫

确实有一段时间没怎么写爬虫了,最近又安排了写爬虫的任务,其实很多东西写过一份,之后再做大部分是复制粘贴代码,然后修改一下。所以这里总结一下通用的地方,之后编写爬虫的时候就可以直接拿来用了。


一、使用urllib2库

对于一些简单的网站,需要获取的信息又是以json格式返回时,我一般喜欢用urllib2库直接写爬虫获取。

 

代码模板:

python">import urllib2
import urllib
import json
 
requrl = "http://www.baidu.com"  # 输入要抓取的网站
 
# 如果有要post给requrl的数据,以dict的形式
post_data = {'pageIndex':1, 'pagesize':12}
post_data_urlencode = urllib.urlencode(post_data)  
 
 
req = urllib2.Request(url=requrl, data=post_data_urlencode)
res_data = urllib2.urlopen(req)
res = res_data.read()   # 这里返回的是response中的一个json格式串,res是str类型
 
# json.dumps:dict转成str
# json.loads: str转成dict
# 将数据转换为dict,方便取出数据
json_data = json.loads(res)
 

二、使用selenium

python">from selenium import webdriver
 
# 使用PhantomJS就不会在每次启动的时候都弹出浏览器了
driver = webdriver.PhantomJS()   
requrl = "http://www.baidu.com"
driver.get(requrl)
 
# 通过xpath获取到想要的元素
elements = driver.find_elements_by_xpath('//div[@class="wd"]')
for element in elements:
next_url = element.get_attribute("href")
# 这里获取到下一个需要抓取的网址后,就可以进入下一个函数了
 
driver.quit()

三、使用scrapy

spiders文件夹下自己创建一个.py文件,代码如下:

python">from scrapy.spiders import Spider
from hospital.items import hospital_301
# hospital是整个工程的文件名, hospital_301是你要传入的item的类名
from scrapy.selector import Selector
import scrapy
 
# hospital_spider这个类名可改
class hospital_spider(Spider):
    # 爬虫的名字,用于启动爬虫的时候用
    # 启动爬虫命令:scrapy crawl 爬虫名字
    name = "301hospital"
    # allowed_domains = ['http://www.301hospital.com.cn']
    start_urls = ["http://www.301hospital.com.cn/web/expert/myhc/yyzj.html"]
 
    def parse(self, response):
    	sel = Selector(response)
 
    	# 取一个链接
    	elements = sel.xpath("//div[@class="keshiMenu"]//a/@href").extract()
    	for element in elements:
    	if element == '?':
    	   pass
    	else:
    	   # 拼接起来
    	   next_url = "http://www.301hospital.com.cn/" + element
    	   # 进入下一个函数
    	   yield scrapy.Request(url, callback=self.parse_department)
 
    	# 若有item传入则使用下面这个形式
    	# yield scrapy.Request(url, meta={'item': item1}, callback=self.parse_detail)
 
    def parse_detail(self, response):
    	.....
        # 处理完直接return item,pipeline即可收到这个item
        item1 = response.meta['item']
        return item1

items.py文件代码如下:

python">from scrapy import Item, Field
 
class HospitalItem(Item):
    # define the fields for your item here like:
    # name = scrapy.Field()
    pass
 
 
class hospital_301(Item):
    name = Field()  # 专家名字
    title = Field()  # 职称
    department = Field()  # 科室
    introduction = Field()  # 详细介绍
    specialty = Field()  # 医师特长
    visit_info = Field()  # 出诊信息
    photo = Field()  # 照片
    link = Field()

pipeline.py代码如下:

python"># -*- coding: utf-8 -*-
 
# Define your item pipelines here
#
# Don't forget to add your pipeline to the ITEM_PIPELINES setting
# See: http://doc.scrapy.org/en/latest/topics/item-pipeline.html
 
 
import MySQLdb.cursors
from twisted.enterprise import adbapi
from hospital.items import hospital_301  # hospital为工程文件夹的名字,hospital_301为要传入item的名字
from scrapy.xlib.pydispatch import dispatcher
from scrapy import signals
from scrapy.utils.project import get_project_settings
from scrapy import log
import chardet
 
SETTINGS = get_project_settings()
 
 
class HospitalPipeline(object):
    @classmethod
    def from_crawler(cls, crawler):
        return cls(crawler.stats)
 
    def __init__(self, stats):
        # Instantiate DB
        self.dbpool = adbapi.ConnectionPool('MySQLdb',
                                            host=SETTINGS['DB_HOST'],
                                            user=SETTINGS['DB_USER'],
                                            passwd=SETTINGS['DB_PASSWD'],
                                            port=SETTINGS['DB_PORT'],
                                            db=SETTINGS['DB_DB'],
                                            charset='utf8',
                                            use_unicode=True,
                                            cursorclass=MySQLdb.cursors.DictCursor
                                            )
        self.stats = stats
        dispatcher.connect(self.spider_closed, signals.spider_closed)
 
    def spider_closed(self, spider):
        """ Cleanup function, called after crawing has finished to close open
            objects.
            Close ConnectionPool. """
        self.dbpool.close()
 
    def process_item(self, item, spider):
        query = self.dbpool.runInteraction(self._insert_record, item)
        query.addErrback(self._handle_error)
        return item
 
    def _insert_record(self, tx, item):
    	name = ""
    	title = ""
    	department = ""
    	introduction = ""
    	specialty = ""
    	visit_info = ""
    	photo = ""
    	# 进行元素的获取,都使用try的形式,不然如果有一个元素为空,取出报错,整个程序会中断
    	try:
        	name = str(item['name']).decode('raw_unicode_escape').replace("[u'姓名:", "").replace("']", "")
        except:
        	pass
        try:
        	title = item['title'][0]
        except:
        	pass
    try:
        department = item['department'][0].replace("科室:", "")
    except:
    	pass
 
    try:
        	introduction = item['introduction'][0]
        except:
        	pass
 
        try:
        	specialty = item['specialty'][0]
        except:
        	pass
 
        try:
        	visit_info = ''.join(item['visit_info'])
        except:
        	pass
 
        try:
        	photo = str(item['photo']).decode('raw_unicode_escape')
        except:
        	pass
 
        # 这一步有时候可删除,需要加上的原因是有时候中文存入数据库会出现乱码的情况
        name = name.encode('utf-8')
        title = title.encode('utf-8')
        department = department.encode('utf-8')
        introduction = introduction.encode('utf-8')
        specialty = specialty.encode('utf-8')
        visit_info = visit_info.encode('utf-8')
        photo = photo.encode('utf-8')
 
        # 用于调试用
        # print "name--", name
        # print "title--", title
        # print "department--", department
        # print "introduction--", introduction
        # print "specialty--", specialty
        # print "visit_info--", visit_info
        # print "photo--", photo
 
        sql = "INSERT INTO hospital_301 VALUES ('%s', '%s', '%s', '%s', '%s', '%s', '%s')" % \
              (name, title, department, introduction, specialty, visit_info, photo)
 
        # print sql
        tx.execute(sql)
        print "yes"
 
    def _handle_error(self, e):
        log.err(e)

settings.py代码如下:

python"># -*- coding: utf-8 -*-
 
BOT_NAME = 'hospital'
 
SPIDER_MODULES = ['hospital.spiders']
NEWSPIDER_MODULE = 'hospital.spiders'
 
COOKIES_ENABLED = False  
 
DOWNLOAD_DELAY = 7  # 下载延迟时间
 
LOG_LEVEL = 'INFO'
 
# 数据库参数
DB_HOST = 'localhost'
DB_PORT = 3306  # 端口
DB_USER = 'root'	# 账号
DB_PASSWD = 'xxx' # 密码
DB_DB = 'hospitals'	# 数据库名
 
ITEM_PIPELINES = {
    'hospital.pipelines.HospitalPipeline': 300,  # hospital用工程的文件名替换
}

如需要下载图片,代码如下:

python">photo_url = "http://www.hfyy.cn/bbyy/upload/2015-5/2015052660742901.jpg"
# 给定图片存放名称
filename = 'd:\\photos\\' + name + '.jpg'
# 文件名是否存在
try:
    urllib.urlretrieve(photo_url, filename)
    print "finished"
except Exception, e:
    print e




http://www.niftyadmin.cn/n/1436617.html

相关文章

python装饰器学习小结

一、应用场景 装饰模式有很多经典的使用场景,例如插入日志、性能测试、事物处理等等,有了装饰器,就可以提取大量函数中与本身功能无关的类似代码,从而达到代码重用的目的。好好利用装饰器可以方便代码结构,让代码更清…

c++实现装饰器模式

一、定义 装饰器模式(DecoratorPattern)允许向一个现有的对象添加新的功能,同时又不改变其结构。 使用情况:如果需要添加新功能,但又不想修改定义好的接口或者抽象类,此时适合用装饰模式。 应用场景举例&a…

python的yield使用

在python中,yield被称之为generator(生成器)。 下面举个小例子来理解,yield在程序是怎么执行的 代码: def func():print "begin"yield 1print "mid"yield 2print "end"f func() f.ne…

linux下的一些常见命令学习

Linux常用命令学习 Linux常用命令学习1 显示用户最近登录信息 last命令2将文件按列显示 awk命令3 查看文件内容 cat命令4 实时显示进程资源占用情况 top命令5显示当前运行的进程快照 ps命令6 显示文件内容 more命令7 显示文件内容 less命令8 查看分区可见空间 df命令Linux面试题…

网络编程知识点梳理

文章目录1、 你怎么理解HTTP协议?2、 HTTP和HTTPS的区别?3、 ISO七层网络模型/五层网络模型/TCPIP四层网络模型4、 TCP和UDP的区别5、 同步和异步、阻塞和非阻塞、长线程和短线程的区别?6、 现在要访问www.baidu.com,整个过程是怎…

网络分析工具

在后台开发中网络通信这一块非常重要,在处理定位问题或者多方联调时,需要用到网络分析工具。这里学习一下ping、tcpdump、netstat和lsof这4个网络分析工具的使用。 1 ping2 tcpdump3netstat4 lsof 1、 ping 介绍:ping(Packet Int…

redis的安装和配置

Redis是常用基于内存的Key-Value数据库,支持多种数据结构,高效,快速。用Redis可以很轻松解决高并发的数据访问问题,做为实时监控信号处理也非常不错。 Redis支持五种数据类型:string(字符串)&am…

【leetcode】657. Judge Route Circle

一、题目描述 Initially, there is a Robot at position (0, 0). Given a sequence of its moves, judge if this robot makes a circle, which means it moves back to the original place. The move sequence is represented by a string. And each move is represent by a c…