1. Web服務(wù)器網(wǎng)站
進(jìn)一步把前面的Web網(wǎng)站的mysql.html, python.html, java.html豐富其中 的內(nèi)容,并加上圖形:
mysql.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>mysql</title>
</head>
<body>
<h3>MySQL數(shù)據(jù)庫(kù)</h3>
<div>
MySQL是一個(gè)關(guān)系型數(shù)據(jù)庫(kù)管理系統(tǒng),由瑞典MySQL AB 公司開(kāi)發(fā),目前屬于 Oracle 旗 下產(chǎn)品。MySQL 是最流行的關(guān)系型數(shù)據(jù)庫(kù)管理系統(tǒng)之一,在 WEB 應(yīng)用方面,MySQL是 最好的 RDBMS (Relational Database Management System,關(guān)系數(shù)據(jù)庫(kù)管理系統(tǒng)) 應(yīng)用軟 件。
</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程序設(shè)計(jì)</h3>
<div>
Java是一門面向?qū)ο缶幊陶Z(yǔ)言,不僅吸收了C++語(yǔ)言的各種優(yōu) 點(diǎn),還摒棄了C++里難以理解的多繼承、指針等概念,因此 Java語(yǔ)言具有功能強(qiáng)大和簡(jiǎn)單易用兩個(gè)特征。Java語(yǔ)言作為靜 態(tài)面向?qū)ο缶幊陶Z(yǔ)言的代表,極好地實(shí)現(xiàn)了面向?qū)ο罄碚?,?許程序員以優(yōu)雅的思維方式進(jìn)行復(fù)雜的編程.
</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程序設(shè)計(jì)</h3>
<div>
Python (英國(guó)發(fā)音:/?pa?θ?n/ 美國(guó)發(fā)音:/?pa?θɑ?n/), 是一 種面向?qū)ο蟮慕忉屝陀?jì)算機(jī)程序設(shè)計(jì)語(yǔ)言,由荷蘭人Guido van Rossum于1989年發(fā)明,第一個(gè)公開(kāi)發(fā)行版發(fā)行于1991年。
</div>
<div>
<img src="python.jpg">
</div>
<a href="books.html">Home</a>
</body>
</html>
2. 爬取網(wǎng)站的復(fù)雜數(shù)據(jù)
服務(wù)器server.py程序還是前面3.2的,如下:
import flask
import os
app = 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 data
if __name__ == "__main__":
app.run()
????????爬取網(wǎng)站中的mysql, python, java的簡(jiǎn)介與圖像。我們看到簡(jiǎn)介在網(wǎng)頁(yè)的第一個(gè)<div>中,圖像在<img>中,而且只有這3個(gè)網(wǎng)頁(yè)有這樣的特征,
設(shè)計(jì)客戶端client.py程序如下:
from bs4 import BeautifulSoup
import urllib.request
def spider(url):
global urls
if 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")
# 判斷這個(gè)url頁(yè)面是否有<div>與<img>,如果有就獲取第一個(gè)<div>的文字,下載第一個(gè)<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 + "/" + href
spider(url)
except Exception as err:
print(err)
start_url = "http://127.0.0.1:5000"
urls = []
spider(start_url)
print("The End")
運(yùn)行結(jié)果如下:
?程序執(zhí)行完畢后還看到下載了3個(gè)文件:
"downloaded-mysql.jpg"、 "downloadedpython.jpg"、"downloaded-java.jpg"
3. 爬取程序的改進(jìn)
(1)服務(wù)器程序
????????由于我們的web網(wǎng)站時(shí)本地的,因此下載圖像非???,而實(shí)際應(yīng)用中 Web網(wǎng)站是遠(yuǎn)程的一個(gè)服務(wù)器,由于網(wǎng)絡(luò)原因可能下載會(huì)比較慢。為了 模擬這個(gè)過(guò)程,
改進(jìn)后的服務(wù)器serverUpdate.py程序如下:
import flask
import os
import random
import time
app = flask.Flask(__name__)
def getFile(fileName):
data = b""
if os.path.exists(fileName):
fobj = open(fileName, "rb")
data = fobj.read()
fobj.close()
# 隨機(jī)等待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 data
if __name__ == "__main__":
app.run()
? ? ? ? 該程序在每次返回一個(gè)網(wǎng)頁(yè)或者圖像的函數(shù)getFile中都隨機(jī)等待了1- 10秒,這個(gè)過(guò)程十分類似網(wǎng)絡(luò)條件較差的情景,即訪問(wèn)任何一個(gè)網(wǎng)頁(yè)或 者圖像都有1-10秒的延遲。
(2)客戶端程序
????????從目前的程序來(lái)看這個(gè)程序在下載一個(gè)圖像時(shí)是等待的,如果這個(gè)圖像很大,那么下載時(shí)間很長(zhǎng),程序就必須一直等待,其它網(wǎng)頁(yè)就無(wú)法繼續(xù)訪問(wèn),即卡死在一個(gè)網(wǎng)頁(yè)的圖像下載處。為了避免這個(gè)問(wèn)題,一般可以對(duì)程序做以下改進(jìn):
- 設(shè)置urllib.request下載圖像的時(shí)間,如果超過(guò)一定時(shí)間還沒(méi)有完 成下載就放棄;
- 設(shè)置下載過(guò)程是一個(gè)與主線程不同的子線程,子線程完成下載 任務(wù),不影響主線程繼續(xù)訪問(wèn)別的網(wǎng)頁(yè)。????????
改進(jìn)后的客戶端clientUpdate.py程序如下:
from bs4 import BeautifulSoup
import urllib.request
import threading
def download(url, fileName):
try:
# 設(shè)置下載時(shí)間最長(zhǎng)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 urls
if 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")
# 判斷這個(gè)url頁(yè)面是否有<div>與<img>,如果有就獲取第一個(gè)<div>的文字,下載第一個(gè)<img>的圖像
if len(divs) > 0 and len(imgs) > 0:
print(divs[0].text)
url = start_url + "/" + imgs[0]["src"]
# 啟動(dòng)一個(gè)下載線程下載圖像
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 + "/" + href
spider(url)
except Exception as err:
print(err)
start_url = "http://127.0.0.1:5000"
urls = []
threads = []
spider(start_url)
# 等待所有線程執(zhí)行完畢
for t in threads:
t.join()
print("The End")
執(zhí)行結(jié)果如下:
?從結(jié)果看到訪問(wèn)java.htm網(wǎng)頁(yè)后沒(méi)有及時(shí)完成java.jpg的下載,java.jpg是在訪問(wèn) network.htm網(wǎng)頁(yè)后才完成下載的,這就是多線程的過(guò)程。文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-478898.html
下一篇文章:3.5 實(shí)踐項(xiàng)目——爬取網(wǎng)站的圖像文件文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-478898.html
到了這里,關(guān)于【爬蟲(chóng)】3.4 爬取網(wǎng)站復(fù)雜數(shù)據(jù)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!