【爬虫】3.4 爬取网站复杂数据
1. Web服務器網站
進一步把前面的Web網站的mysql.html, python.html, java.html豐富其中 的內容,并加上圖形:
mysql.html
<!DOCTYPE html> <html lang="en"> <head><meta charset="UTF-8"><title>mysql</title> </head> <body><h3>MySQL數據庫</h3><div>MySQL是一個關系型數據庫管理系統,由瑞典MySQL AB 公司開發,目前屬于 Oracle 旗 下產品。MySQL 是最流行的關系型數據庫管理系統之一,在 WEB 應用方面,MySQL是 最好的 RDBMS (Relational Database Management System,關系數據庫管理系統) 應用軟 件。</div><div><img src="mysql.jpg" /></div><a href="books.html">Home</a> </body> </html>java.html
<!DOCTYPE html> <html lang="en"> <head><meta charset="UTF-8"><title>java</title> </head> <body><h3>Java程序設計</h3><div>Java是一門面向對象編程語言,不僅吸收了C++語言的各種優 點,還摒棄了C++里難以理解的多繼承、指針等概念,因此 Java語言具有功能強大和簡單易用兩個特征。Java語言作為靜 態面向對象編程語言的代表,極好地實現了面向對象理論,允 許程序員以優雅的思維方式進行復雜的編程.</div><div><img src="java.jpg"></div><a href="books.html">Home</a> </body> </html>python.html
<!DOCTYPE html> <html lang="en"> <head><meta charset="UTF-8"><title>python</title> </head> <body><h3>Python程序設計</h3><div>Python (英國發音:/?pa?θ?n/ 美國發音:/?pa?θɑ?n/), 是一 種面向對象的解釋型計算機程序設計語言,由荷蘭人Guido van Rossum于1989年發明,第一個公開發行版發行于1991年。</div><div><img src="python.jpg"></div><a href="books.html">Home</a> </body> </html>2. 爬取網站的復雜數據
服務器server.py程序還是前面3.2的,如下:
import flask import osapp = flask.Flask(__name__)def getFile(fileName):data = b""if os.path.exists(fileName):fobj = open(fileName, "rb")data = fobj.read()fobj.close()return data@app.route("/") def index():return getFile("books.html")@app.route("/<section>") def process(section):data = ""if section != "":data = getFile(section)return dataif __name__ == "__main__":app.run()????????爬取網站中的mysql, python, java的簡介與圖像。我們看到簡介在網頁的第一個<div>中,圖像在<img>中,而且只有這3個網頁有這樣的特征,
設計客戶端client.py程序如下:
from bs4 import BeautifulSoup import urllib.requestdef spider(url):global urlsif url not in urls:urls.append(url)try:data = urllib.request.urlopen(url)data = data.read().decode()soup = BeautifulSoup(data, "lxml")print(soup.find("h3").text)divs = soup.select("div")imgs = soup.select("img")# 判斷這個url頁面是否有<div>與<img>,如果有就獲取第一個<div>的文字,下載第一個<img>的圖像if len(divs) > 0 and len(imgs) > 0:print(divs[0].text)url = start_url + "/" + imgs[0]["src"]urllib.request.urlretrieve(url, "downloaded-" + imgs[0]["src"])print("download-", imgs[0]["src"])links = soup.select("a")for link in links:href = link["href"]url = start_url + "/" + hrefspider(url)except Exception as err:print(err)start_url = "http://127.0.0.1:5000" urls = [] spider(start_url) print("The End")運行結果如下:
?程序執行完畢后還看到下載了3個文件:
"downloaded-mysql.jpg"、 "downloadedpython.jpg"、"downloaded-java.jpg"
3. 爬取程序的改進
(1)服務器程序
????????由于我們的web網站時本地的,因此下載圖像非常快,而實際應用中 Web網站是遠程的一個服務器,由于網絡原因可能下載會比較慢。為了 模擬這個過程,
改進后的服務器serverUpdate.py程序如下:
import flask import os import random import timeapp = flask.Flask(__name__)def getFile(fileName):data = b""if os.path.exists(fileName):fobj = open(fileName, "rb")data = fobj.read()fobj.close()# 隨機等待1-10秒time.sleep(random.randint(1, 10))return data@app.route("/") def index():return getFile("books.html")@app.route("/<section>") def process(section):data = ""if section != "":data = getFile(section)return dataif __name__ == "__main__":app.run()? ? ? ? 該程序在每次返回一個網頁或者圖像的函數getFile中都隨機等待了1- 10秒,這個過程十分類似網絡條件較差的情景,即訪問任何一個網頁或 者圖像都有1-10秒的延遲。
(2)客戶端程序
????????從目前的程序來看這個程序在下載一個圖像時是等待的,如果這個圖像很大,那么下載時間很長,程序就必須一直等待,其它網頁就無法繼續訪問,即卡死在一個網頁的圖像下載處。為了避免這個問題,一般可以對程序做以下改進:
- 設置urllib.request下載圖像的時間,如果超過一定時間還沒有完 成下載就放棄;
- 設置下載過程是一個與主線程不同的子線程,子線程完成下載 任務,不影響主線程繼續訪問別的網頁。????????
改進后的客戶端clientUpdate.py程序如下:
from bs4 import BeautifulSoup import urllib.request import threadingdef download(url, fileName):try:# 設置下載時間最長100秒data = urllib.request.urlopen(url, timeout=100)data = data.read()fobj = open("download" + fileName, "wb")fobj.write(data)fobj.close()print("download", fileName)except Exception as err:print(err)def spider(url):global urlsif url not in urls:urls.append(url)try:data = urllib.request.urlopen(url)data = data.read().decode()soup = BeautifulSoup(data, "lxml")print(soup.find("h3").text)links = soup.select("a")divs = soup.select("div")imgs = soup.select("img")# 判斷這個url頁面是否有<div>與<img>,如果有就獲取第一個<div>的文字,下載第一個<img>的圖像if len(divs) > 0 and len(imgs) > 0:print(divs[0].text)url = start_url + "/" + imgs[0]["src"]# 啟動一個下載線程下載圖像T = threading.Thread(target=download, args=(url, imgs[0]["src"]))T.setDaemon(False)T.start()threads.append(T)for link in links:href = link["href"]url = start_url + "/" + hrefspider(url)except Exception as err:print(err)start_url = "http://127.0.0.1:5000" urls = [] threads = [] spider(start_url) # 等待所有線程執行完畢 for t in threads:t.join() print("The End")執行結果如下:
?從結果看到訪問java.htm網頁后沒有及時完成java.jpg的下載,java.jpg是在訪問 network.htm網頁后才完成下載的,這就是多線程的過程。
總結
以上是生活随笔為你收集整理的【爬虫】3.4 爬取网站复杂数据的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 四年Java 欢聚时代面经,已拿offe
- 下一篇: 学习使我快乐 第五天