爬蟲框架Scrapy(四)
使用框架Scrapy開發(fā)一個(gè)爬蟲只需要四步:
創(chuàng)建項(xiàng)目:scrapy startproject proname(項(xiàng)目名字混驰,不區(qū)分大小寫)
明確目標(biāo)(編寫items.py):明確你想要抓取的目標(biāo)
制作爬蟲(spiders/xxspider.py):制作爬蟲開始爬取網(wǎng)頁(yè)
存儲(chǔ)內(nèi)容(pipelines.py):設(shè)計(jì)管道存儲(chǔ)爬取內(nèi)容秒咐,存入數(shù)據(jù)庫(kù)
1风瘦、創(chuàng)建項(xiàng)目
在開始爬取之前划滋,必須創(chuàng)建一個(gè)新的Scrapy項(xiàng)目巩螃。進(jìn)入自定義的項(xiàng)目目錄中媒峡,運(yùn)行下列命令:
scrapy startproject spiderProject
生成項(xiàng)目scrapy_1,目錄如下:
spiderProject/
spiderProject1/
spiders/
__init__.py
items.py
middlewares.py
pipelines.py
settings.py
scrapy.cfg
這些文件分別是:
scrapy.cfg: 項(xiàng)目的配置文件翠桦。
spiderProject/: 項(xiàng)目的Python模塊,將會(huì)從這里引用代碼捧韵。
spiderProject/items.py: 項(xiàng)目的目標(biāo)文件市咆。
spiderProject/pipelines.py: 項(xiàng)目的管道文件。
spiderProject/settings.py: 項(xiàng)目的設(shè)置文件再来。
spiderProject/spiders/: 存儲(chǔ)爬蟲代碼目錄。
2、明確目標(biāo)
抓取豆瓣電影TOP250網(wǎng)站所有的電影以及評(píng)分https://movie.douban.com/top250芒篷。
再項(xiàng)目的目標(biāo)文件創(chuàng)建搜变,制作一個(gè)Item容器。
Item容器是存儲(chǔ)爬取數(shù)據(jù)的容器针炉,使用方式類似于python字典Dict挠他,我們需要對(duì)爬取的數(shù)據(jù)分析,定義爬取記錄的數(shù)據(jù)結(jié)構(gòu)篡帕,然后建立相應(yīng)的字段殖侵。
在spiderProject/items.py文件添加:
import scrapy
# 爬取豆瓣電影以及評(píng)分
class SpiderprojectItem(scrapy.Item):
name = scrapy.Field()
score = scrapy.Field()
3、制作爬蟲
3.1镰烧、創(chuàng)建爬蟲douban
在當(dāng)前目錄下輸入命令:
scrapy genspider douban "douban.cn"
創(chuàng)建一個(gè)名為douban的爬蟲拢军,將在scrapy_1/spiders目錄下生成一個(gè)douban.py文件,并指定爬取域的范圍怔鳖。
import scrapy
class DooubanSpider(scrapy.Spider):
name = 'doouban'
allowed_domains = ['doouban.cn']
start_urls = ['http://doouban.cn/']
def parse(self, response):
pass
3.2茉唉、確立屬性方法
要實(shí)現(xiàn)一個(gè)Spider爬蟲, 必須有一個(gè)繼承scrapy.Spider類的子類结执,并確定了三個(gè)強(qiáng)制的屬性 和 一個(gè)方法度陆。
name屬性
name = "" :這個(gè)爬蟲的識(shí)別名稱,必須是唯一的献幔,在不同的爬蟲必須定義不同的名字懂傀。
allow_domains屬性
allow_domains = [] 是搜索的域名范圍,也就是爬蟲的約束區(qū)域蜡感,規(guī)定爬蟲只爬取這個(gè)域名下的網(wǎng)頁(yè)蹬蚁,不存在的URL會(huì)被忽略。
start_urls屬性
start_urls = () :爬取的URL元祖/列表铸敏。爬蟲從這里開始抓取數(shù)據(jù)缚忧,所以,第一次下載的數(shù)據(jù)將會(huì)從這些urls開始杈笔。其他子URL將會(huì)從這些起始URL中繼承性生成闪水。
parse方法
parse(self, response) :解析的方法,每個(gè)初始URL完成下載后將被調(diào)用蒙具,調(diào)用的時(shí)候傳入從每一個(gè)URL傳回的Response對(duì)象來作為唯一參數(shù)球榆,主要作用如下:
1、負(fù)責(zé)解析返回的網(wǎng)頁(yè)數(shù)據(jù)(response.body)禁筏,提取結(jié)構(gòu)化數(shù)據(jù)(生成item)持钉;
2、生成需要下一頁(yè)的URL請(qǐng)求篱昔;
3.3每强、配置文件
如果執(zhí)行爬蟲過程中始腾,出現(xiàn)403錯(cuò)誤:
HTTP status code is not handled or not a llowed
我們需要將自身偽裝成瀏覽器請(qǐng)求
修改配置文件settings.py,添加如下(添加任意一個(gè)均可以):
import random
# 需要設(shè)置USER_AGENT,假裝自己是瀏覽器訪問網(wǎng)頁(yè)
user_agent_list = [
"Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_8; en-us) AppleWebKit/534.50 (KHTML, like Gecko) Version/5.1 Safari/534.50",
"Mozilla/5.0 (Windows; U; Windows NT 6.1; en-us) AppleWebKit/534.50 (KHTML, like Gecko) Version/5.1 Safari/534.50",
"Mozilla/5.0 (Windows NT 10.0; WOW64; rv:38.0) Gecko/20100101 Firefox/38.0",
"Mozilla/5.0 (Windows NT 10.0; WOW64; Trident/7.0; .NET4.0C; .NET4.0E; .NET CLR 2.0.50727; .NET CLR 3.0.30729; .NET CLR 3.5.30729; InfoPath.3; rv:11.0) like Gecko",
"Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0)",
"Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.0; Trident/4.0)",
"Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0)",
"Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)",
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10.6; rv:2.0.1) Gecko/20100101 Firefox/4.0.1",
"Mozilla/5.0 (Windows NT 6.1; rv:2.0.1) Gecko/20100101 Firefox/4.0.1",
"Opera/9.80 (Macintosh; Intel Mac OS X 10.6.8; U; en) Presto/2.8.131 Version/11.11",
"Opera/9.80 (Windows NT 6.1; U; en) Presto/2.8.131 Version/11.11",
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_0) AppleWebKit/535.11 (KHTML, like Gecko) Chrome/17.0.963.56 Safari/535.11"
]
USER_AGENT = random.choice(user_agent_list)
同時(shí)settings文件加入mongoDB的配置信息
# MONGODB 主機(jī)名
MONGODB_HOST = "127.0.0.1"
# MONGODB 端口號(hào)
MONGODB_PORT = 27017
# 數(shù)據(jù)庫(kù)名稱
MONGODB_DBNAME = "Douban"
# 存放數(shù)據(jù)的表名稱
MONGODB_SHEETNAME = "doubanmovies"
3.4、配置爬蟲文件
爬取需要的數(shù)據(jù)空执,形成json文件
from spiderProject.items import SpiderprojectItem
class DoubanSpider(scrapy.Spider):
name = 'douban'
allowed_domains = ['douban.cn']
start_urls = ['http://movie.douban.com/top250']
def parse(self, response):
for item in response.css('.item'):
movie = SpiderprojectItem()
title = item.css('.hd span.title::text').extract_first()
star = item.css('.star span.rating_num::text').extract_first()
movie['name'] = title
movie['score'] = star
yield movie
# 獲取下一頁(yè)url
# next_url = response.css('span.next a::attr("href")').extract_first()
# if next_url is not None:
# url = self.start_urls[0]+next_url
# yield scrapy.Request(url=url,callback=self.parse())
4浪箭、設(shè)計(jì)管道,存儲(chǔ)數(shù)據(jù)mongoDB
# 存入mongoDB數(shù)據(jù)庫(kù)
import pymongo
from spiderProject.settings import MONGODB_HOST
from spiderProject.settings import MONGODB_PORT
from spiderProject.settings import MONGODB_DBNAME
from spiderProject.settings import MONGODB_SHEETNAME
class SpiderprojectPipeline:
def __init__(self):
host = MONGODB_HOST
port = MONGODB_PORT
dbname = MONGODB_DBNAME
tablename = MONGODB_SHEETNAME
# 創(chuàng)建數(shù)據(jù)庫(kù)連接
self.client = pymongo.MongoClient(
host=host,
port=port
)
# 指定數(shù)據(jù)庫(kù)
mydb=self.client[dbname]
# 指定數(shù)據(jù)表
self.dbtable = mydb[tablename]
def process_item(self, item, spider):
# 將數(shù)據(jù)存入數(shù)據(jù)表
data = dict[item]
self.dbtable.insert(data)
return item
def close_spider(self, spider):
self.f.close()
同時(shí)需要在settings文件下打開管道文件配置(只需要解開注釋就可以了)辨绊。
# 啟用管道
# 優(yōu)先級(jí) 現(xiàn)在是300 范圍 0-1000 越小 優(yōu)先級(jí)越高
ITEM_PIPELINES = {
'spiderProject.pipelines.SpiderprojectPipeline': 300,
}
5奶栖、運(yùn)行爬蟲
scrapy crawl douban