python爬蟲(1)——簡單的爬取網頁的資訊
阿新 • • 發佈:2019-01-05
獲取網上真實的語料資料,本身對Py的掌握不是很好,記錄下自己學習的過程,希望對你有幫助。
#python3
獲得taoeba的語料(不知道從哪翻到的這個網站,有各國語言的句子,訪問速度較慢
檢視你的瀏覽器的user-agent ——位址列中輸入:about:version 檢視user-agents
直接指令碼訪問,可能會出現這樣的報錯:
...
...
urllib.error.HTTPError: HTTP Error 403: Forbidden
這樣比單執行緒快了許多,爬取網頁資訊還是不要訪問太快了。。對網站的伺服器友好一點。。
下一步將要學習一下動態網頁資訊的爬取,通過scrapy 深入瞭解一下執行緒程序,以及網路爬蟲機制(作業系統?網路?)
發現什麼問題,或者有什麼建議請告訴我~謝謝~
# -*- coding: utf-8 -*-
import requests
from bs4 import BeautifulSoup as BS
import time
import re
python3中的urllib以及requestshttp://blog.csdn.net/drdairen/article/details/51149498#對句子列表網頁進行獲取,得到一個list包含句子連結 def get_selist(url): try: response = requests.get(url, headers=headers) #訪問所有句子列表 soup = BS(response.text, "lxml") #解析網頁 urls = soup.find_all(href=re.compile('.*/cmn/sentences/show/[0-9].*')) #找到所有我要的<a>標籤 得到一個list 接下來提取元素的href sentences = [] #存href for i in urls: #遍歷<a>標籤列表 sentences.append(i.get('href')) #get('href')只能對標籤字串操作,剛開始我直接對urls.get()是不可以的。。。 sentences = list(set(sentences)) #對得到的href列表去重 return sentences #返回連結的list except Exception as e: #網頁訪問錯誤就返回空列表 a = [] print('獲取句子列表失敗 連結為'+url) return a
headers = {'User-Agent':'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36'}
url = 'https://tatoeba.org/cmn/sentences/show_all_in/cmn/none/none/indifferent/page:' #分析發現所有中文句子的網頁規律
h = 'https://tatoeba.org' #為了訪問詞的地址 地址一般為../cmn/sentences/show/[0-9]
header用來假裝自己是個瀏覽器,有時也會需要cookie等。#對句子列表網頁進行獲取,得到一個list包含句子連結 def get_selist(url): try: response = requests.get(url, headers=headers) #訪問所有句子列表 soup = BS(response.text, "lxml") #解析網頁 urls = soup.find_all(href=re.compile('.*/cmn/sentences/show/[0-9].*')) #找到所有我要的<a>標籤 得到一個list 接下來提取元素的href sentences = [] #存href for i in urls: #遍歷<a>標籤列表 sentences.append(i.get('href')) #get('href')只能對標籤字串操作,剛開始我直接對urls.get()是不可以的。。。 sentences = list(set(sentences)) #對得到的href列表去重 return sentences #返回連結的list except Exception as e: #網頁訪問錯誤就返回空列表 a = [] print('獲取句子列表失敗 連結為'+url) return a
# 解析一個詞的網頁 返回fr/es的兩個列表[zh:fr,zh:fr],[zh:sp,zh:sp]
def getext(url1):
def text(tag):#內建函式,傳入一個標籤列表,獲得每一個text資訊,返回一個list
a = []
for i in tag:
a.append(i.get_text())
return a
try:
response = requests.get(url1, headers=headers)#同上
soup = BS(response.text, "lxml")
zh = text(soup.find_all('div', attrs={'lang': 'zh-Hans'})) #獲得對應屬性的標籤 這個找的是含有中文的標籤
fr = text(soup.find_all('div', attrs={'lang': 'fr'}))#法語
sp = text(soup.find_all('div', attrs={'lang': 'es'})) #西班牙語
zh2fr = []
zh2sp = [] #兩個list存對應語料資訊
for f in fr: #將對應語料格式化
zh2fr.append(zh[0] + '||||' + f)
for s in sp:
zh2sp.append(zh[0] + '||||' + s)
print(zh2fr, zh2sp)
return zh2fr, zh2sp #返回兩個列表,方便寫入兩個檔案
except Exception as e: #同樣錯誤則返回空
a = []
b = []
print('獲取句子失敗 連結為'+url1)
return a,b
#因為得到的是對應語料的list 構造一個函式 方便寫入檔案
def _write(file,fr):
if len(fr):
for i in fr:
file.write(i+'\n')
#開始的操作~
zh2fr = open('zh2fr','a',encoding='utf-8') #將要寫入的兩個檔案
zh2sp = open('zh2sp','a',encoding='utf-8')
url_list = []
#獲得所有句子的連結,應該是有5094頁,取了一頁測試
for i in range(1,2):
url_list.extend(get_selist(url+str(i))) #將列表連在一起
begin = time.time() #時間記錄
#訪問所有的句子連結,獲得平行語料並寫入檔案
for j in url_list:
(fr,sp) = getext(h+j)
_write(zh2fr,fr)
_write(zh2sp,sp)
end = time.time()
print('use time %s'%(end-begin))
#對了,不要忘了close開啟的檔案
zh2ru.close()
zh2fr.close()
這個指令碼的效率不是很高,首先因為網站訪問很慢,時間不一定(一套下來10多秒也有可能,幾百秒也有可能。。)
# 主要加了sleep random 避免訪問過快
# 解析一個詞的網頁 返回fr/es的兩個列表[zh:fr,zh:fr]
#多加了一門語言
def getext(url1):
def text(tag):
a = []
for i in tag:
a.append(i.get_text())
return a
try:
time.sleep(random.randint(0,5)) #避免句子同時訪問太快。。沒有對執行緒任務的時間控制,感覺這麼寫比較簡單。。
response = requests.get(url1, headers=headers)
soup = BS(response.text, "lxml")
zh = text(soup.find_all('div', attrs={'lang': 'zh-Hans'}))
fr = text(soup.find_all('div', attrs={'lang': 'fr'}))
sp = text(soup.find_all('div', attrs={'lang': 'es'}))
ru = text(soup.find_all('div', attrs={'lang': 'ru'}))
zh2fr = []
zh2sp = []
zh2ru = []
for f in fr:
zh2fr.append(zh[0] + '||||' + f)
for s in sp:
zh2sp.append(zh[0] + '||||' + s)
for r in ru:
zh2ru.append(zh[0] + '||||' + r)
print(zh2fr, zh2sp, zh2ru)
return zh2fr, zh2sp, zh2ru
except Exception as e:
a = []
print('獲取句子失敗 連結為'+url1)
return a,a,a
# 主要加了這個函式 獲得句子連結沒有用多執行緒,訪問句子網頁用的,因為訪問太快會報錯。。雖然不會被封,但是無法獲得資訊了
#訪問一頁,就獲取所有的句子,避免了過快訪問
def get_url(i):
url_list = (get_selist(url + str(i))) #獲得句子的網址列表,用的寫好的函式。
print('page'+str(i)+'ok---'+str(len(url_list)))
def fetch_content(url): #任務函式
(fr, sp, ru) = getext(h + url)
_write(zh2fr, fr)
_write(zh2sp, sp)
_write(zh2ru, ru)
threads2 = [] #多執行緒任務的封裝
for j in url_list:
t = Thread(target=fetch_content, args=[j])
t.start()
threads2.append(t)
for t in threads2:
t.join()
這樣比單執行緒快了許多,爬取網頁資訊還是不要訪問太快了。。對網站的伺服器友好一點。。
下一步將要學習一下動態網頁資訊的爬取,通過scrapy 深入瞭解一下執行緒程序,以及網路爬蟲機制(作業系統?網路?)
發現什麼問題,或者有什麼建議請告訴我~謝謝~