第一個Scrapy框架爬蟲
我要爬取的網站是一個網課網站http://www.itcast.cn/channel/teacher.shtml,爬取內容是所有老師的基本信息。
1.創建一個基於Scrapy框架的爬蟲項目
進入自定義的項目目錄中,運行下列命令:
**ITCast爲項目名字**
scrapy startproject ITCast
2. 結構化所獲取數據字段
打開項目目錄找到items.py,這個模塊,我覺得就像java中的對象實體類的定義,但是所有類都必須是scrapy.Item的子類,這裏我定義一個ItCastItem類,用於保存每一位老師的基本信息。
import scrapy
class ItCastItem(scrapy.Item):
name = scrapy.Field() # 教師名字
title = scrapy.Field()# 教師職稱
info = scrapy.Field() # 教師履歷
3.製作爬蟲
1.我們必須創建一個爬蟲(可以在pycharm下的terminal下輸入該命令)
scrapy genspider itcast "itcast.cn"
創建的爬蟲會自動生成在你的項目的spiders目錄下,並且自動生成文件itcast .py,裏面還自動添加了一些基本代碼
每個爬蟲都強制要求擁有三個屬性
- name :爬蟲的名字,由常見爬蟲的時候指定
- allowed_domains:是搜索的域名範圍,即爬蟲的作用域,一般指定該域名之後,爬蟲則只會爬取該域名下的網頁,不存在的URL將會被忽略
- start_urls:爬取的URL元祖/列表。爬蟲從這裏開始抓取數據,所以,第一次下載的數據將會從這些urls開始。其他子URL將會從這些起始URL中繼承性生成。
2.修改parse()方法,解析頁面數據
# -*- coding: utf-8 -*-
import scrapy
from ITCast.items import ItCastItem
from lxml import etree
class ItCastSpider(scrapy.Spider):
name = 'itcast' # 這個爬蟲的識別名稱,必須是唯一的,在不同的爬蟲必須定義不同的名字。
allowed_domains = ['itcast.cn'] # 是搜索的域名範圍,也就是爬蟲的約束區域,規定爬蟲只爬取這個域名下的網頁,不存在的URL會被忽略。
start_urls = ['http://www.itcast.cn/channel/teacher.shtml'] # 爬取的URL元祖/列表。爬蟲從這裏開始抓取數據,所以,第一次下載的數據將會從這些urls開始
# 解析的方法
def parse(self, response):
'''
解析返回的網頁數據(response.body),提取結構化數據(生成item)
:param response:
:return:
'''
print(response.body)
filename = "teacher.html"
with open(filename,'wb') as f:
f.write(response.body)
context = response.xpath('/html/head/title/text()')
# print(context)
# 提取網站標題
title = context.extract_first()
print(title)
html = etree.HTML(response.text)
print("===============\n\n\n\n\n\n")
#print(text.xpath("//div[@class='li_txt']"))
print("===============\n\n\n\n\n\n")
items = [] # 存放老師信息對象的列表
# print(response.xpath("//div[@class='li_txt'][1]"))
# print(html.xpath("//div[@class='li_txt']"))
# 獲取每一個教師對象,進行封裝
for each in html.xpath("//div[@class='li_txt']"):
# 將得到的數據封裝到一個'ItcastItem'對象中
item = ItCastItem()
name = each.xpath(".//h3/text()")
title = each.xpath(".//h4/text()")
info = each.xpath(".//p/text()")
# 封裝,xpath返回的是包含一個元素的列表,所以用name[0]
item['name'] = name[0]
item['title'] = title[0]
item['info'] = info[0]
items.append(item)
# 返回結果集
return items
5.運行爬蟲並保存數據
運行爬蟲有簡單的主要幾種方式模式(還有其他的沒列出來)
scrapy crawl itcast //單純的運行爬蟲,結果會在終端打印出來
scrapy crawl itcast -o teachers.json //運行蟲,並保存爲json文件數據格式
scrapy crawl itcast -o teachers.jsonlines //運行爬蟲,並保存爲jsonlines文件數據格式
scrapy crawl itacst -o teachers.csv //運行爬蟲,並保存爲csv文件數據格式(可以使用Excel打開)
scrapy crawl itcast -o teachers.xml //運行爬蟲,並保存爲xml文件數據格式
6.查看結果
回到項目目錄可以看到已經生成的文件,給大家看一下我的項目目錄和生成的文件
7. 錯誤總結
解析頁面的時候,總是不能正確的拿到數據,每次拿到的數據都是空列表,因此用了chropath插件慢慢的在谷歌瀏覽器嘗試,後來才發現,原來是在獲取每個item的info,name,title的時候,使用錯了xpath。
(錯誤的)我之前填寫的是:
name = each.xpath("//h3/text()")
title = each.xpath("//h4/text()")
info = each.xpath("//p/text()")
這裏的each是網頁中的每一位教師的div外框,因此我想通過這種方式,然後直接獲取該div下的第一個h3,h4 , p標籤,但是一直獲取的都是錯誤數據
我查詢錯誤數據來源,發現竟然是頁面的第一個h3,h4 , p標籤的內容,我頓時醒悟。
(正確的)應該是這樣:
name = each.xpath("./h3/text()")
title = each.xpath(".//h4/text()")
info = each.xpath(".//p/text()")
加個點後,就是取當前元素的子元素,否則它就從最開始查找了。
要是有些地方不對,請大家幫忙指出哦,歡迎大家留言。
一起共勉!!!