鳥網作者:別來這套
出自蜂鳥網-旅行攝影,原貼鏈接:https://m.fengniao.com/thread/10974178.html
謝謝上面回帖的朋友!其實這次登高只是我計劃中的預演。本打算經過這次試探行的登山后,帶上三腳架、多個鏡頭和照明燈、冰爪(100多塊買的)等閉門瞎想準備的登山物品來一次正式的登高。平時沒事總喜歡扒拉谷歌地球,對這個亞隆冰川特別好奇。百度介紹這個冰川是12公里,但我在地圖上測量直線長度超過30公里!在谷歌地球上看,然烏湖和米堆冰川(他們3個挨在一起)簡直無法和亞隆冰川相比。我多次在谷歌地球上一個海拔5100處山腰上,模擬拍下亞隆冰川、東嘎冰川、來古村和白日嘎三座山峰。然而連日陰雨讓我的計劃基本泡湯。看手機上天氣預報未來無數天依然連雨,只好在第4天悻悻的結束來古村之旅,搭乘一對杭州夫婦的自駕車出村。
雖然白日嘎峰沒有露面,但隱藏山里的高山湖在海拔4700米還是出現了。
漂亮的杭州自駕游女士在給小朋友發禮品。來古村客棧和小學一個院子。小學也就20多個孩子。
如果不是翻看照片,我都不知道這露出的高山湖。
由于這次登高高度不足,也可能是登高位子選的不對,對亞隆冰川的拍攝效果遠遠沒有達到我的期待。在家好好鍛煉身體吧!爭取下一次的來古村之行,登到5200米海拔,用體力彌補技術的不足吧。
再見了,來古村!其實雨中的來古村也非常美,只是我一門心思想著登高,沒有靜下心體會而已。
還有高海拔處的野花,秋季綻放的藍色小花,我也只是匆匆拍一下而已。
其實,和亞隆冰川對著的,高懸在村東的東嘎冰川,也非常壯觀。
再見了!來古村。等我攢夠了假期和錢,我會多住幾天的。
應該是一個為了村里低年齡段的孩子而設立的小學。
歡迎關注 蜂鳥網微信公眾號:fengniaoweixin
不久,我在 LearnML 子論壇上看到一篇帖子。樓主在這篇帖子中提到,他需要為自己的機器學習項目抓取網頁數據。很多人在回帖中給出了自己的方法,主要是學習如何使用 BeautifulSoup 和 Selenium。
我曾在一些 數據科學項目中使用過 BeautifulSoup 和 Selenium。在本文中,我將告訴你如何用一些有用的數據抓取一個網頁,并將其轉換成 pandas 數據結構(DataFrame)。
為什么要將其轉換成數據結構呢?這是因為大部分機器學習庫都能處理 pandas 數據結構,并且只需少量修改就可對你的模型進行編輯。
首先,我們要在維基百科上找到一個表來轉換成數據結構。我抓取的這張表,展示的是維基百科上瀏覽量最大的運動員數據。
其中一項大量的工作就是,通過瀏覽 HTML 樹來得到我們需要的表。
通過 request 和 regex 庫,我們開始使用 BeautifulSoup。
from bs4 import BeautifulSoup
import requests
import re
import pandas as pd
復制代碼
下面,我們將從網頁中提取 HTML 代碼:
website_url=requests.get('https://en.wikipedia.org/wiki/Wikipedia:Multiyear_ranking_of_most_viewed_pages').text
soup=BeautifulSoup(website_url, 'lxml')
print(soup.prettify())
</a>
</li>
<li id="footer-places-disclaimer">
<a href="/wiki/Wikipedia:General_disclaimer" title="Wikipedia:General disclaimer">
Disclaimers
</a>
</li>
<li id="footer-places-contact">
<a href="//en.wikipedia.org/wiki/Wikipedia:Contact_us">
Contact Wikipedia
</a>
</li>
<li id="footer-places-mobileview">
<a class="noprint stopMobileRedirectTog
復制代碼
從語料庫中收集所有的表,我們有一個較小的表面區域來搜索。
wiki_tables=soup.find_all('table', class_='wikitable')
wiki_tables
復制代碼
因為存在很多表,所以需要一種過濾它們的方法。
據我們所知,Cristiano Ronaldo(也就是葡萄牙足球運動員 C 羅)有一個錨標記,這可能在幾個表中是獨一無二的。
通過 Cristiano Ronaldo 文本,我們可以過濾那些被錨標記的表。此外,我們還發現一些包含這個錨標記的父元素。
links=[]
for table in wiki_tables:
_table=table.find('a', string=re.compile('Cristiano Ronaldo'))
if not _table:
continue
print(_table)
_parent=_table.parent
print(_parent)
links.append(_parent)
<a href="/wiki/Cristiano_Ronaldo" title="Cristiano Ronaldo">Cristiano Ronaldo</a>
<td style="text-align: left;"><a href="/wiki/Cristiano_Ronaldo" title="Cristiano Ronaldo">Cristiano Ronaldo</a>
</td>
<a href="/wiki/Cristiano_Ronaldo" title="Cristiano Ronaldo">Cristiano Ronaldo</a>
<td style="text-align: left;"><a href="/wiki/Cristiano_Ronaldo" title="Cristiano Ronaldo">Cristiano Ronaldo</a>
</td>
<a href="/wiki/Cristiano_Ronaldo" title="Cristiano Ronaldo">Cristiano Ronaldo</a>
<td style="text-align: left;"><a href="/wiki/Cristiano_Ronaldo" title="Cristiano Ronaldo">Cristiano Ronaldo</a>
</td>
復制代碼
父元素只顯示單元格。
這是一個帶有瀏覽器 web 開發工具的單元格。
parent_lst=[]
for anchor in links:
_=anchor.find_parents('tbody')
print(_)
parent_lst.append(_)
復制代碼
利用 tbody,我們可以返回包含以前的錨標記的其他表。
為進一步過濾,我們可以在以下表中的不同標題進行搜索:
for i in parent_lst:
print(i[0].find('tr'))
tr>
<th>Rank*</th>
<th>Page</th>
<th>Views in millions
</th></tr>
<tr>
<th>Rank</th>
<th>Page</th>
<th>Views in millions
</th></tr>
<tr>
<th>Rank</th>
<th>Page</th>
<th>Sport</th>
<th>Views in millions
</th></tr>
復制代碼
第三張看起來很像我們所需要的表。
接下來,我們開始創建必要的邏輯來提取并清理我們需要的細節。
sports_table=parent_lst[2]
complete_row=[]
for i in sports_table:
rows=i.find_all('tr')
print('\n--------row--------\n')
print(rows)
for row in rows:
cells=row.find_all('td')
print('\n-------cells--------\n')
print(cells)
if not cells:
continue
rank=cells[0].text.strip('\n')
page_name=cells[1].find('a').text
sport=cells[2].find('a').text
views=cells[3].text.strip('\n')
print('\n-------CLEAN--------\n')
print(rank)
print(page_name)
print(sport)
print(views)
complete_row.append([rank, page_name, sport, views])
for i in complete_row:
print(i)
復制代碼
分解一下:
sports_table=parent_lst[2]
complete_row=[]
復制代碼
下面我們從上面的列表中選擇第三個元素。這就是我們需要的表。
接下來創建一個空列表,用于存儲每行的詳細信息。在遍歷這個表的時候,建立一個循環,遍歷表中的每一行,并將其保存到 rows 變量中。
for i in sports_table:
rows=i.find_all('tr')
print('\n--------row--------\n')
print(rows)
復制代碼
for row in rows:
cells=row.find_all('td')
print('\n-------cells--------\n')
print(cells)
復制代碼
建立了嵌套的循環。遍歷上一個循環中保存的每個行。在遍歷這些單元格時,我們將每個單元格保存在一個新的變量。
if not cells:
continue
復制代碼
這段簡短的代碼允許我們在從單元格中提取文本時,避免空單元格并防止發生錯誤。
rank=cells[0].text.strip('\n')
page_name=cells[1].find('a').text
sport=cells[2].find('a').text
views=cells[3].text.strip('\n')
復制代碼
在此,我們將各種單元格清理為純文本格式。清除后的值保存在其列名下的變量中。
print('\n-------CLEAN--------\n')
print(rank)
print(page_name)
print(sport)
print(views)
complete_row.append([rank, page_name, sport, views])
復制代碼
此處,我們向行列表添加這些值。然后輸出清理后的值。
-------cells--------
[<td>13
</td>, <td style="text-align: left;"><a href="/wiki/Conor_McGregor" title="Conor McGregor">Conor McGregor</a>
</td>, <td><a href="/wiki/Mixed_martial_arts" title="Mixed martial arts">Mixed martial arts</a>
</td>, <td>43
</td>]
-------CLEAN--------
13
Conor McGregor
Mixed martial arts
43
復制代碼
下面將其轉換為數據結構:
headers=['Rank', 'Name', 'Sport', 'Views Mil']
df=pd.DataFrame(complete_row, columns=headers)
df
復制代碼
現在你可以在機器學習項目中使用的 pandas 數據結構了。你可以使用自己喜歡的庫來擬合模型數據。
作者介紹:
Tobi Olabode,對技術感興趣,目前主要關注機器學習。
原文鏈接:
https://blog.devgenius.io/how-to-scrape-a-website-for-your-ml-project-c3a4d6f160c7
目前對于Python來說,使用最多的功能肯定是Python爬蟲。比如搶購茅臺以及刷評論,蓋樓等抽獎活動貼,都可以應用到爬蟲的相關知識。
而學習Python爬蟲,不僅可以增加自己的知識儲備,豐富自己的知識庫,而且還能幫助自己增加額外的收入。
所以,今天博主將通過某個蓋樓活動貼,來實現自動評論蓋樓抽獎功能。本篇內容接著上一篇博文的內容進行全自動蓋樓刷評論講解。
一般來說,我們參加某個網站的蓋樓抽獎活動,并不是僅僅只參加一個,而是多個蓋樓活動一起參加。
這個時候,我們就需要分析評論的鏈接是怎么區分不同帖子進行評論的,如上篇的刷帖鏈接,具體格式如下:
https://club.hihonor.com/cn/forum.php?mod=post&action=reply&fid=154&tid=21089001&extra=page%3D1&replysubmit=yes&infloat=yes&handlekey=fastpost&inajax=1
這里面用于區分不同帖子的鍵是tid,不妨大家可以會看上一篇博文評論帖子的鏈接,是不是同樣有一個21089001的數字。
而經過博主的測試,該網站評論post請求網址除了tid之外,其他數據是一模一樣的并不需要變更。所以,我們切換新帖子評論時,只需要替換tid的值就行。
讀者可以自行隨便打開一個該網站的帖子,我們一般會得到如下形式的字符串帖子鏈接:
https://club.hihonor.com/cn/thread-26194745-1-1.html
這里,我們需要應用字符串切割知識,來獲取鏈接字符串中的長數字字符串26194745。具體代碼如下:
import re
# 獲取需要評論的所有網頁鏈接
url_start="https://club.hihonor.com/cn/forum.php?mod=post&action=reply&fid=4515&tid="
url_end="&extra=page%3D1&replysubmit=yes&infloat=yes&handlekey=fastpost&inajax=1"
url=[] # 評論網頁
txt_url=[] # 提供的網頁(格式不同)
f=open("隨機帖子.txt", "r", encoding='utf-8')
line=f.readline() # 讀取第一行
while line:
if re.match(r'http[s]?://(?:[a-zA-Z]|[0-9]|[$-_@.&+]|[!*\(\),]|(?:%[0-9a-fA-F][0-9a-fA-F]))+', line):
txt_url.append(line.strip()) # 列表增加
line=f.readline() # 讀取下一行
datas=[]
headers=[]
for i in txt_url:
url_start="https://club.hihonor.com/cn/forum.php?mod=post&action=reply&fid=4515&tid="
url_end="&extra=page%3D1&replysubmit=yes&infloat=yes&handlekey=fastpost&inajax=1"
url.append(url_start + i.split("-")[1] + url_end)
這里,博主將一大堆需要評論的鏈接全部放到文本文件之中,然后通過讀取文件獲取每一行鏈接數據(其中用正則表達式判斷鏈接是否合法)。
在通過遍歷鏈接切分獲取帖子標識數字字符串,最后進行拼接獲取到真正的post評論鏈接。
在眾多的網站蓋樓活動中,官方網站一般都會檢測是否有內容重復,一般同一個賬號多次評論重復的內容,肯定會被禁止評論一段時間。
所以,我們需要將評論的內容多樣化,比如說這個網站要我們稱贊手機性能進行蓋樓抽獎,那么我們就需要備用一些評論文字,方便程序隨機獲取。
具體文字放置在txt文件中,我們通過下面的代碼進行讀取:
# 獲取需要評論的文本內容
txt_contents=[]
f=open("回帖文案.txt", "r", encoding='utf-8')
line=f.readline() # 讀取第一行
while line:
if line.strip() !="":
txt_contents.append(line.strip()) # 列表增加
line=f.readline() # 讀取下一行
print(txt_contents)
count=len(txt_contents)
假如,我們是需要參加游戲論壇的蓋樓評論活動,那么就可以用下面的文本進行隨機提取評論,樣本越多,重復性越少。
一般來說,這種經常有活動的網站都是需要驗證登錄的。而各個網站的驗證碼算法都不相同,怎么自動登錄賬號,往往就非常關鍵了。
對于識別驗證碼,我們要么用百度,騰訊,阿里云提供的文字識別接口,但是博主試過了都無法保證百分百識別成功,而且最高識別準備率都不到50%。
如果需要自己寫機器學習識別算法,那么學過機器學習的都應該知道,這個是需要龐大的標記的,哪怕你真的做出來,恐怕人家網站又會換了驗證方式。
這種驗證碼與防驗證碼一直在進步,花費大量實現標注驗證碼這些內容,往往會浪費大量的時間,到最后人家可能又換了。
所以,博主的建議還是自己手動輸入驗證碼,也就這一步輸入驗證碼手動,其他的全自動。完整代碼如下:
import random
import time
from selenium import webdriver
import requests
import re
# 獲取需要評論的文本內容
txt_contents=[]
f=open("回帖文案.txt", "r", encoding='utf-8')
line=f.readline() # 讀取第一行
while line:
if line.strip() !="":
txt_contents.append(line.strip()) # 列表增加
line=f.readline() # 讀取下一行
print(txt_contents)
count=len(txt_contents)
# 獲取需要評論的所有網頁鏈接
url_start="https://club.hihonor.com/cn/forum.php?mod=post&action=reply&fid=4515&tid="
url_end="&extra=page%3D1&replysubmit=yes&infloat=yes&handlekey=fastpost&inajax=1"
url=[] # 評論網頁
txt_url=[] # 提供的網頁(格式不同)
f=open("隨機帖子.txt", "r", encoding='utf-8')
line=f.readline() # 讀取第一行
while line:
if re.match(r'http[s]?://(?:[a-zA-Z]|[0-9]|[$-_@.&+]|[!*\(\),]|(?:%[0-9a-fA-F][0-9a-fA-F]))+', line):
txt_url.append(line.strip()) # 列表增加
line=f.readline() # 讀取下一行
datas=[]
headers=[]
for i in txt_url:
url_start="https://club.hihonor.com/cn/forum.php?mod=post&action=reply&fid=4515&tid="
url_end="&extra=page%3D1&replysubmit=yes&infloat=yes&handlekey=fastpost&inajax=1"
url.append(url_start + i.split("-")[1] + url_end)
# 獲取賬號
usernames=[]
f=open("賬號.txt", "r", encoding='utf-8')
line=f.readline() # 讀取第一行
while line:
usernames.append(line.strip()) # 列表增加
line=f.readline() # 讀取下一行
for name in usernames:
browser=webdriver.Chrome()
browser.implicitly_wait(10)
browser.get("https://club.hihonor.com/cn/")
time.sleep(5)
login_text=browser.find_element_by_xpath("//*[@id='loginandreg']/a[1]")
login_text.click()
username=browser.find_element_by_xpath(
'/html/body/div[1]/div[2]/div/div/div[1]/div[3]/span/div[1]/span/div[2]/div[2]/div/input')
password=browser.find_element_by_xpath(
'/html/body/div[1]/div[2]/div/div/div[1]/div[3]/span/div[1]/span/div[3]/div/div/div/input')
username.send_keys(name)
password.send_keys("密碼")#所有蓋樓刷評論賬號密碼盡量統一,這樣就可以只在txt每行輸入賬號即可
sign=browser.find_element_by_xpath(
'/html/body/div[1]/div[2]/div/div/div[1]/div[3]/span/div[1]/span/div[6]/div/div/span/span')
#等待10秒,讓程序運行者輸入驗證碼
time.sleep(10)
sign.click()
time.sleep(2)
cookie=[item["name"] + "=" + item["value"] for item in browser.get_cookies()]
cookiestr=';'.join(item for item in cookie)
url2="https://club.hihonor.com/cn/thread-26183971-1-1.html"
time.sleep(2)
browser.get(url2)
posttime=browser.find_element_by_id("posttime")
posttime=posttime.get_attribute("value")
formhash=browser.find_element_by_name("formhash")
formhash=formhash.get_attribute("value")
browser.close()
data={
"formhash": formhash,
"posttime": posttime,
"usesig": "1",
"message": txt_contents[0],
}
header={
"accept": "application/json, text/javascript, */*; q=0.01",
"Accept-Encoding": "gzip, deflate, br",
"Accept-Language": "zh-CN,zh;q=0.9",
"Content-Length": "146",
"sec-ch-ua": '"Google Chrome";v="87", "\"Not;A\\Brand";v="99", "Chromium";v="87"',
"User-Agent": "Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.141 Mobile Safari/537.36",
"Cookie": cookiestr,
"Content-Type": "application/x-www-form-urlencoded; charset=UTF-8",
"X-Requested-With": "XMLHttpRequest",
}
datas.append(data)
headers.append(header)
while True:
z=0
if int(time.strftime("%H%M%S")) <=220000:
url_num=random.sample(range(0, len(url)), len(url))
for i in url_num:
j=1
for data, header in zip(datas, headers):
data['message']=txt_contents[random.randint(0, count - 1)]
res=requests.post(url=url[i], data=data, headers=header)
if '回復發布成功' in res.text:
print("賬號{0}回復成功".format(j))
else:
print(res.text)
j +=1
z +=1
time.sleep(5)
print("已經評論{0}條".format(str(z)))
如上面代碼所示,我們的賬號也是用txt文件統一處理的,這樣可以達到多個賬號同時刷的目的,當然一般網站獲獎都不能是同一個IP,這里讀者可以通過代理來處理。
其實登錄后,隨便一個帖子都有posttime與formhash兩個值,只要你隨機打開一個帖子(url2)就可以通過爬蟲知識獲取。
運行效果如頭圖所示。
*請認真填寫需求信息,我們會在24小時內與您取得聯系。