《 利用 Python36,基於 Scrapy 框架的爬蟲思路 》

(一)引言 利用爬蟲抓取網頁數據已經是常見技能,八爪魚等工具也比較方便,但導出數據需要付費。從長遠來看,靜下心來學習爬蟲也未嘗不可。不過還是有一定難度,需要有一些編程的基礎,坑多,一般人就別整了。我做的第一個爬蟲作品,歡迎有需要的朋友參考。(二)目標網址(這是一個JS渲染的網頁,網頁直接無法解析,風格:網址不變下實現表格的翻頁 ):

chinabond.com.cn/jsp/in

(三)工具:Scrapy + Selenium + Phantomjs,平臺:Python36。 Python36 -> Pycharm -> CMD -> Scrapy -> Selenium -> Phantomjs -> chrome + xpath helper -> MySQL ->Navicat Premium -> ODBC配置 -> Stata等應用層 (四)編程思路:1. Scrapy 下新建項目文件和主爬蟲文件解析網頁;2. 通過 Chrome + Xpath helper 插件,對網頁進行初步分析,確定需要抓取的變數欄位,獲取 xpath 地址;3. 編寫 Items.py,這部分主要是定義要抓取和寫入的欄位:class MyspiderItem(scrapy.Item):# 以下定義要爬蟲的欄位名

id = scrapy.Field() # 序號

name = scrapy.Field() # 簡稱code = scrapy.Field() # 代碼issuer = scrapy.Field() # 發行人date = scrapy.Field() # 日期amount = scrapy.Field() # 發行量payway = scrapy.Field() # 付息方式rate = scrapy.Field() # 利率deadline = scrapy.Field() # 期限startdate = scrapy.Field() # 起息日

enddate = scrapy.Field() # 到期日

# 以下定義要寫入 MySQL 資料庫的欄位,注意變數名要與 MySQL 數據表中的欄位一致。def get_insert_sql(self):insert_sql="""insert into chinabond(id,name,code,issuer,date,

amount,

payway,rate,deadline,startdate,enddate)VALUES (%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s)"""params=(self["id"],

self["name"],

self["code"],self["issuer"],self["date"],self["amount"],self["payway"],self["rate"],self["deadline"],self["startdate"],self["enddate"],

)

return insert_sql,params4. 編寫通道文件: piplines.py,這部分主要完成將數據寫入 MySQL 等資料庫:from twisted.enterprise import adbapiimport pymysqlimport pymysql.cursorsclass MyspiderPipeline(object):def __init__(self,dbpool):self.dbpool = dbpool@classmethod

def from_settings(cls,settings):

dbpool = adbapi.ConnectionPool("pymysql",host="localhost",db="mysql",user="root",password="123",charset="utf8mb4",cursorclass=pymysql.cursors.DictCursor,use_unicode = True

)

return cls(dbpool)def process_item(self,item,spider):self.dbpool.runInteraction(self.do_insert,item)def do_insert(self,cursor,item):insert_sql,params=item.get_insert_sql()cursor.execute(insert_sql,params)5. 在 setting.py 開啟通道文件,配置網頁請求的頭信息等:(1)考慮以網站可能存在防爬機制,為避免伺服器識別為機器訪問,需要偽裝成人工瀏覽器訪問,啟用頭信息:DEFAULT_REQUEST_HEADERS = {

host: www.chinabond.com.cn,

accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,accept-language: zh-CN,zh;q=0.9,user-agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.75 Safari/537.36,}(2)啟用 piplines.py 通道文件:# Configure item pipelines# See scrapy.readthedocs.org/ITEM_PIPELINES = {myspider.pipelines.MyspiderPipeline: 300,}6. 編寫主爬蟲文件: D:scrapymyspidermysipderspiderschinabond.py,需要在其中完成對網頁的解析和元素的提取。 # -*- coding: utf-8 -*-import scrapyfrom myspider.items import MyspiderItemfrom selenium import webdriverfrom selenium.webdriver.support.ui import WebDriverWaitclass ChinabondSpider(scrapy.Spider):name = chinabondallowed_domains = [chinabond.com.cn]start_urls = ["chinabond.com.cn/jsp/in"]def parse(self, response):driver = webdriver.PhantomJS(executable_path=C:\Python36\phantomjs-2.1.1-windows\bin\phantomjs.exe)url = "chinabond.com.cn/jsp/in"driver.get(url)page_n = len(driver.find_elements_by_xpath(//*[@id="sel"]/option)) # 計算總頁數,數值型;for j in range(1,3): # 在頁數範圍內爬蟲!這裡測試為 3,全爬應為:range(1,page_n+1)page_i = int(driver.find_element_by_xpath(//*[@id="nowpage"]).text) # 獲得當前頁的頁碼,數值型;print("當前是第:" + str(page_i) + "頁,共計:" + str(page_n) + "頁")for i in range(2, 22): # 爬取當前頁面數據,2—22 表示頁面數據是從2-22行,不含表頭,一般 tr 代表行,td代表列。item = MyspiderItem()item[id] = driver.find_element_by_xpath("//*[@id=bodyTable]/tbody/tr[" + str(i) + "]/td[1]").textitem[name] = driver.find_element_by_xpath("//*[@id=bodyTable]/tbody/tr[" + str(i) + "]/td[2]").textitem[code] = driver.find_element_by_xpath("//*[@id=bodyTable]/tbody/tr[" + str(i) + "]/td[3]").textitem[issuer] = driver.find_element_by_xpath("//*[@id=bodyTable]/tbody/tr[" + str(i) + "]/td[4]").textitem[date] = driver.find_element_by_xpath("//*[@id=bodyTable]/tbody/tr[" + str(i) + "]/td[5]").textitem["amount"] = driver.find_element_by_xpath("//*[@id=bodyTable]/tbody/tr[" + str(i) + "]/td[6]").textitem["payway"] = driver.find_element_by_xpath("//*[@id=bodyTable]/tbody/tr[" + str(i) + "]/td[7]").textitem["rate"] = driver.find_element_by_xpath("//*[@id=bodyTable]/tbody/tr[" + str(i) + "]/td[9]").textitem["deadline"] = driver.find_element_by_xpath("//*[@id=bodyTable]/tbody/tr[" + str(i) + "]/td[10]").textitem["startdate"] = driver.find_element_by_xpath("//*[@id=bodyTable]/tbody/tr[" + str(i) + "]/td[11]").textitem["enddate"] = driver.find_element_by_xpath("//*[@id=bodyTable]/tbody/tr[" + str(i) + "]/td[12]").textyield item # 發送當前頁數據driver.find_element_by_xpath(//*[@id="xiayiye"]/a/img).click() # 點擊下一頁;def load_ok(driver): # 判斷下一頁是否已經完成載入if int(driver.find_element_by_xpath(//*[@id="nowpage"]).text) != page_i:return 1else:return 0WebDriverWait(driver,20).until(load_ok) # 等待載入完成。# yield scrapy.Request(url, callback=self.parse) # 注意,在本例中,翻頁後網址不變,網頁是JS渲染得到的,因此直接不可解析。因此,也是使用 selenium + Phantomjs 的理由。該句如果網址有變化才考慮回傳網頁請求,本例是直接兩重循還得到。但循環時要先等待網頁載入完成纔可進行,必須要有這個判斷函數。(五)運行之,大功告成,哈哈!1. 爬蟲過程圖(164頁,3270條記錄): 2. 數據注入到 MySQL 的截圖:3. Stata 走 ODBC 通道將數據導入結果(附錄A) 安裝 Scrapy:# python 下載包:lfd.uci.edu/~gohlke/pyt blog.csdn.net/HHTNAN/ar# pip3 安裝 Scray 爬蟲框架的方法:# ------------------------------------# 1.運行CMD,切換到Python目錄,安裝pip:python -m pip install --upgrade pip --force-reinstall# 說明:安裝後的pip3存在於Scripts目錄下,可在CMD中切換到 PythonScripts下,運行 pip3 -V 查看版本。# 2.在CMD中,進入Scripts目錄下,運行pip3來安裝 Scrapy 框架:pip3 install scrapy# 說明:可能遇到的錯誤:# ?Microsoft Visual C++ 14.0 is required 這一步報錯了,缺少VC組件!# 解決方案1:(不推薦)提示:landinghub.visualstudio.com,到頁面上下載!建議翻牆後安裝,否則會報錯!# # 解決方案2:(推薦):lfd.uci.edu/~gohlke/pyt下載twisted對應版本的whl文件Twisted?17.5.0?cp36?cp36m?win_amd64.whl),# 文件名中,cp後面是python版本,amd64代表64位,運行pip3 install C:python36Twisted-17.5.0-cp36-cp36m-win_amd64.whl。# 安裝完成後,再次運行:pip3 install Scrapy1### 3.安裝 Win32Py,地址:百度sourceforge.net/project# 檢查是否成功:import win32com,不報錯為OK!## 4.在CMD中添加路徑:path C:Python36;%path%# path C:Python36Scripts;%path%## 5.chrome XPath Helper:Ctrl + Shift + X 激活 XPath Helper 的控制檯,然後您可以在 Query 文本框中# 輸入相應 XPath 進行調試了,提取的結果將被顯示在旁邊的 Result 文本框.# 5.使用firefox瀏覽器,安裝Xpath插件:搜索框中輸入:WebDriver Element Locator,點擊Add to firefox## 6.在python中安裝MySQLdb,在CMD中切換到 PythonScripts下:pip3 install mysql-python (不支持Python3.6)# 6.在python中安裝pymysql,在CMD中切換到 PythonScripts下:pip3 install pymysql(可支持Python3.6)# 6.下載 pymssql, pip3 install C:python36pymssql-2.1.3-cp36-cp36m-win_amd64.whl# 在Windows下安裝PIP+Phantomjs+Selenium 如果說在使用Python爬取相對正規的網頁使用"urllib2 + BeautifulSoup + 正則表達式"就能搞定的話; 那麼動態生成的信息頁面,如Ajax、JavaScript等就需要通過"Phantomjs + CasperJS + Selenium"來實現了。 pip3 install selenium pip3 install -U selenium Phantomjs: phantomjs.org/ 官網下載解壓到 python36scripts 下。 blog.csdn.net/five3/art * 註:解決:「ImportError: cannot import name webdriver」 問題的方法是:不要將自己編寫的程序起名為:selenium.py,因為環境路徑很可能優先搜索到這個文件,導致python36無法找到其中的模塊。 from selenium import webdriver driver = webdriver.PhantomJS(executable_path=C:\Python36\phantomjs-2.1.1-windows\bin\phantomjs.exe) # 注意:路徑中必須使用雙斜槓才能被識別! driver.get("baidu.com") data = driver.title print(data) * 添加路徑的方法:import os,sys sys.path.append("C:\Python36\phantomjs-2.1.1-windows\bin") * 添加路徑的方法:import os,sys sys.path.append("C:\Python36\phantomjs-2.1.1-windows\bin") (附錄B)Scrapy 框架的使用: 1.環境:進入CMD,添加環境路徑:addpath.cmd,內容如下: path C:Python36;%path% path C:Python36Scripts;%path% 2.建立工程項目(D:scrapymyspider,.myspider,.spiders): scrapy startproject myspider3.建立爬蟲文件(D:scrapyTencentTencentspiderschinabond.py): scrapy genspider chinabond "chinabond.com.cn" 4.進入 pycharm 中編輯;5.隨時在 CMD 中試運行。 cd D: cd D:scrapyTencentTencentspiders scrapy crawl chinabond (附錄C)MySQL 資料庫配置:* mysql-5.7.18-winx64.綠色版 ,解壓到:D:MySQL,此時 MySQL 的程序工作目錄在:D:MySQLin 同時將:my-default.ini(已設定好配置)copy到 MySQL目錄下(D:MySQL),改名:D: MySQL my.ini============================================================================================來源:blog.csdn.net/mhmyqn/ar---------------------------------------------------------------(1)先配置環境變數,把mysql所在目錄的bin目錄添加到path環境變數中,具體請百度。 說明:這一步也可以不要,如果你已經進入了:bin 目錄下。 <1> 右鍵單擊我的電腦->屬性->高級系統設置(高級)->環境變數 點擊系統變數下的新建按鈕 輸入變數名:MYSQL_HOME 輸入變數值:D:mysql <2> 選擇系統變數中的Path 點擊編輯按鈕 在變數值中添加變數值:%MYSQL_HOME%in 注意是在原有變數值後面加上這個變數,用;隔開,不能刪除原來的變數值,(2)CMD 窗口重新以管理員身份運行;(3)CMD中,在 bin 目錄下,安裝 mysql 服務:mysqld --install 顯示:Service successfully installed. (4)啟動 mysql 服務: <1> 先在:INI中設置正確的路徑(假設目錄是:D:MySQL;D:MySQLin): 找到:D:MySQLmy-default.ini,或者自己建立一個my.ini文件,修改或增加如下內容: [mysqld] basedir=D:MySQL datadir=D:MySQLdata 說明:網上有的說配置中的目錄分隔符必須是正斜槓『/』 但是經過實驗,『/』、『』、『\』都沒有問題,都是可以的。 <2> 到 bin 目錄下啟動服務:net start mysql,如果報錯,可考慮先停止、刪除原服務,再安裝並啟動。 mysqld --remove,如果原服務還在:net stop mysql mysqld --install 可能需要初始化一下 data 文件夾(可能需要將原行的刪掉):mysqld --initialize-insecure --user=mysql net start mysql 顯示:MySQL 服務正在啟動 . MySQL 服務已經啟動成功。(5)連接 mysql 服務:mysql -uroot,進入 MySQL 命令行:mysql>(6)退出:exit (7) CMD 下設置 mysql 新密碼:mysqladmin -u root password 123(8)驗證一下用密碼登錄:mysql -uroot -p(9)進入 mysql 後,連接到資料庫(現在已是 mysql 命令行):mysql> use mysql update user set password=password(123) where user=root; 注意,分號結尾。 flush privileges (附錄D)將 MySQL 服務連接到 ODBC 數據通道: ------------------------------------------------------------------------------------* 以下:將 MySQL 配置到 win10 的 ODBC(64位數據源),以方便各軟體走 ODBC 通道訪問。------------------------------------------------------------------------------------* (一)首先請開啟 MySQL 服務(具體資料見附錄A).*(二)為 MySQL 資料庫安裝並配置 ODBC 驅動* (必須安裝MySQL的ODBC驅動,不能用 Win10 自帶的 SQL server)。* 1. 下載地址:dev.mysql.com/downloads,安裝64位驅動。* 2. 參考資料:jingyan.baidu.com/artic* 3. Win10 中:控制面板/管理工具/ODBC(64位數據源),打開後添加:* MySQL ODBC 5.3 Unicode driver 即可。* 填入信息:選 TCP/IP server, 埠號:3306* Data soure name:mysql(隨便填);用戶名:root;密碼:123* Database 選MySQL項(必選), 伺服器:localhost 或 127.0.0.1; * 可以點 Test 按鈕測試一下, 完事點OK就連上了MySQL伺服器.* (三) 例:在 Stata 可操作如下命令:* 1.查看 MySQL 中的資料庫odbc list // 註:之後的操作均可以通過滑鼠進行;* 2.查看 mysql 資料庫中的所有表:odbc query "mysql", dialog(complete)* 3. 查看 chinabond 表中的欄位名:odbc desc "chinabond"* 4. 導入 chinabond 數據表的數據到 stata 內存:* odbc load [extvarlist] [if] [in] , {table("TableName")|exec("SqlStmt")}* [load_options connect_options]* 如果導入錯誤,可以換種方式:通過菜單導入,勾選 「Do not quote SQL table name 」* 等價於加上參數選項:noquote ,因此該參數對於成功導入是很重要的!odbc load, table("chinabond") clear noquote user(root) password(123) dsn("mysql")


推薦閱讀:
相關文章