一.Xpath表達式基礎
1.XPath與正則表達式簡單對比。
(1)XPath表達式效率高一些。
(2)正則表達式功能強大一點。
(3)一般來說,優先選擇XPath,但是XPath解決不了的問題用正則表達式解決。
2.常用的XPath表達式:
/ 逐層提取。
//標籤名 提取所有名爲的標籤。
//標籤名[@屬性=屬性值] 提取屬性爲的標籤。(起限制作用)
@屬性名 代表取某個屬性。
text() 提取標籤下面的文本。
3.實例:
提取網頁的標題:/html/title/text()
提取所有div標籤://div
提取div中
二.噹噹網商品信息爬取實戰
(1)創建爬蟲文件 dangdang
打開cmd進入指定的文件夾,輸入語句:scrapy startproject dangdang 創建爬蟲文件。
創建完之後如圖所示:
(2)創建爬蟲文件,基於basic 文件,域名爲 dangdang.com(域名去主頁url中查)。
在dangdang文件夾下輸入 scrapy genspider -t basic dd dangdang.com
在spiders文件中就新建了一個爬蟲文件,如圖所示:
(3)打開pycham導入dangdandg爬蟲工程,首先打開items.py 編寫爬取目標。
在items.py中創建三個容器:title(用來存儲標題),link(用來存儲鏈接),comment(用來存儲評論數)。
# -*- coding: utf-8 -*-
# Define here the models for your scraped items
#
# See documentation in:
# https://docs.scrapy.org/en/latest/topics/items.html
import scrapy
class DangdangItem(scrapy.Item):
# define the fields for your item here like:
# name = scrapy.Field()
# 創建三個容器
title = scrapy.Field() # 存儲標題
link = scrapy.Field() # 存儲link
comment = scrapy.Field() # 存儲評論數
(4)定義好items.py之後接下來就要編寫爬蟲文件dd.py。
分析網址:
第二頁:http://category.dangdang.com/pg2-cid4008123.html
第三頁:http://category.dangdang.com/pg3-cid4008123.html
很容易就能看出翻頁規律。
提取標題(title):
分析網頁源碼: 分析可知,僅僅靠<a title 並不能篩選出所有的商品標題信息,還必須要有一個限定條件,觀察可知:name="itemlist-picture"可以作爲限定條件。
故XPath表達式可以表示爲:提取所有的a標籤,並且通過name=“itemlist-picture” 定位,然後提取title中的內容:
//a[@name="itemlist-picture”]/@title
同理提取鏈接(link):
//a[@name="itemlist-picture”]/@href
取評論(comment):
//a[@name=“itemlist-review”]/text()
故dd.py編寫如下,for循環是實現分頁爬取,這裏爬取前9頁。
# -*- coding: utf-8 -*-
import scrapy
# 所有的導入都是從核心目錄開始定位。
from dangdang.items import DangdangItem
from scrapy.http import Request
class DdSpider(scrapy.Spider):
name = 'dd'
allowed_domains = ['dangdang.com']
start_urls = ['http://category.dangdang.com/pg1-cid4008123.html']
def parse(self, response):
item = DangdangItem() # 實例化items一個對象。
# 取標題
item["title"] = response.xpath("//a[@name='itemlist-picture' ]/@title").extract() #提取信息。
# 提取鏈接
item["link"] = response.xpath('//a[@name="itemlist-picture" ]/@href').extract()
# 提取評論數量
item["comment"] = response.xpath('//a[@name="itemlist-review"]/text()').extract()
yield item # 將爬取的數據提交到pipelines中進行處理
# 進入for循環實現逐頁爬取。
for i in range(2, 10): # 爬取2-9頁所有的商品信息。
url = 'http://category.dangdang.com/pg'+str(i)+'-cid4008123.html'
# 用yield返回。Request()裏面的參數有網址,回調函數,
yield Request(url, callback=self.parse)
若想不遵循robot協議需要在setting文件裏面設置,將ROBOTSTXT_OBEY 的值由True 改成False。
(5)打開cmd運行爬蟲文件測試一下。
運行結果:
(6) 將爬取的數據放在數據可表格中:
需要用到pipelines.py文件和mysql數據庫,pipelines默認是不開啓的,我們需要去setting中將pipelines開啓。
鏈接Mysql數據庫:打開cmd窗口鍵入:mysql -u root -p 輸入密碼。
創建dangdang數據庫(也可以使用已創建好的數據庫),使用數據庫,並創建表goods來存儲爬取的數據信息。
數據庫創建好之後,在pipelines.py文件中鏈接數據庫。編寫sql語句,將爬取的數據讀入數據庫表格中。執行完sql語句後別放忘記關閉數據庫,注意異常處理。
# -*- coding: utf-8 -*-
import pymysql #導入pymysql模塊。
# Define your item pipelines here
#
# Don't forget to add your pipeline to the ITEM_PIPELINES setting
# See: https://docs.scrapy.org/en/latest/topics/item-pipeline.html
class DangdangPipeline(object):
def process_item(self, item, spider):#用循環將商品遍歷出來。
conn = pymysql.connect(host="127.0.0.1", user="root", passwd="123456", db="dangdang")
for i in range(0, len(item["title"])):
title = item["title"][i]
link = item["link"][i]
comment = item["comment"][i]
# print(title+":"+link+":"+comment)
sql = "insert into goods(title,link,comment) values ('"+title+"','"+link+"','"+comment+"');"
#print(sql)
try:
conn.query(sql) # 執行sql語句
conn.commit()
except Exception as e:
print(e)
conn.close()
return item
再繼續打開cmd窗口執行爬蟲文件
在Mysql中鍵入Select * from goods;語句查詢是否寫入成功。
爬取成功。