2017-06-20 81 views
6

我正在做網絡抓取,作爲學術項目的一部分,重要的是所有鏈接都要遵循實際內容。令人煩惱的是,在「社交媒體管理」網站中存在一些重要的錯誤情況,用戶在其中發佈鏈接以檢測對他們的點擊。訪問社交媒體管理網站上的原始網址

例如,考慮鏈接到http:// + bit.ly +/1P1xh9J的this link on linkis.com(由於SO發佈限制而分開的鏈接),該鏈接又鏈接到http://conservatives4palin.com。出現此問題的原因是linkis.com上的原始鏈接不會自動向前重定向。相反,用戶必須點擊右上角的十字,才能轉到原始網址。

此外,似乎有不同的變化(例如,請參閱linkis.com link 2,其中十字架位於網站的左下角)。這些是我找到的唯一兩個版本,但可能會有更多。請注意,我使用的網絡抓取工具與this one非常相似。由於這是一次性的學術項目,因此通過實際鏈接的功能無需穩定/運行。

如何自動轉到原始網址?最好的方法是設計一個能找到相關鏈接的正則表達式嗎?

+0

沒有時間寫一個答案,但尋找「unshorten URL蟒蛇」可能會給你提示 – Josay

回答

1

該網站遵循共同的架構是,它顯示的網站作爲一個iframe。示例代碼針對兩種情況運行。

爲了讓你可以做這樣的事情最終網址:

import requests                                               
from bs4 import BeautifulSoup                                           

urls = ["http://linkis.com/conservatives4palin.com/uGXam", "http://linkis.com/paper.li/gsoberon/jozY2"]                         
response_data = []                                              

for url in urls:                                              
    response = requests.get(url)                                          
    soup = BeautifulSoup(response.text, 'html.parser')                                     
    short_url = soup.find("iframe", {"id": "source_site"})['src']                                  
    response_data.append(requests.get(short_url).url)                                     

print(response_data) 
+0

This似乎更強大。你試過這個嗎?如果它一致地工作,我會很樂意給你賞金。 – pir

+0

我嘗試了幾個隨機鏈接。你可以用你寫的代碼來插入它。看看它是否有效。 –

+0

您是否知道任何網站對其他類型的推介使用相同的代碼?例如,我不想捕捉嵌入的視頻等。我只需要趕上時間,整個頁面從其他地方嵌入。 – pir

0

說你很能搶href屬性/值:

s = 'href="/url/go/?url=http%3A%2F%2Fbit.ly%2F1P1xh9J"' 

那麼你需要做到以下幾點:

import urllib.parse 
s=s.partition('http') 
s=s[1]+urllib.parse.unquote(s[2][0:-1]) 
s=urllib.parse.unquote(s) 

和S現在將原來的比特串 - 鏈接!

-1

試試下面的代碼:

import requests 

url = 'http://'+'bit.ly'+'/1P1xh9J' 
realsite = requests.get(url) 
print(realsite.url) 

它打印所需的輸出:

http://conservatives4palin.com/2015/11/robert-tracinski-the-climate-change-inquisition-begins.html?utm_source=twitterfeed&utm_medium=twitter 
1

根據你給出的兩個網站,我想你可以試試下面的代碼,以獲得原始它們全部隱藏在javascript的一部分中(我使用的主要刮板代碼來自您發佈的問題):

try: 
 
    from HTMLParser import HTMLParser 
 
except ImportError: 
 
    from html.parser import HTMLParser 
 

 
import requests, re 
 
from contextlib import closing 
 

 
CHUNKSIZE = 1024 
 
reurl = re.compile("\"longUrl\":\"(.*?)\"") 
 
buffer = "" 
 
htmlp = HTMLParser() 
 
with closing(requests.get("http://linkis.com/conservatives4palin.com/uGXam", stream=True)) as res: 
 
    for chunk in res.iter_content(chunk_size=CHUNKSIZE, decode_unicode=True): 
 
     buffer = "".join([buffer, chunk]) 
 
     match = reurl.search(buffer) 
 
     if match: 
 
      print(htmlp.unescape(match.group(1)).replace('\\','')) 
 
      break

+0

你的代碼不能正常工作,導入語句丟失,甚至在添加它們之後,仍然不起作用 – SEDaradji

+0

我添加了導入語句。它似乎在我的環境中工作。您的意思是什麼不工作?是否有任何代碼錯誤發生或只是無法獲取鏈接? – edenPan

+0

它正在工作 – SEDaradji

2

在很多情況下,你將不得不使用瀏覽器自動刮網頁生成使用JavaScript的內容,刮通過一個GET請求返回不會產生你想要的結果的HTML,你有兩個這裏的選項:

  • 嘗試繞過所有額外的javascript請求,以獲得您想要的內容,這可能會非常耗時。
  • 使用瀏覽器自動化,它可以讓你打開一個真正的瀏覽器並自動執行任務,你可以使用Selenium

我一直在開發機器人和刮板多年,現在除非你要求的網頁不依賴JavaScript,否則你應該使用像硒這樣的東西。

下面是一些代碼,以幫助您開始使用硒:

from selenium import webdriver 

#Create a chrome browser instance, other drivers are also available 
driver = webdriver.Chrome()  

#Request a page 
driver.get('http://linkis.com/conservatives4palin.com/uGXam') 

#Select elements on the page and trigger events 
#Selenium supports also xpath and css selectors 
#Clicks the tag with the given id 
driver.find_elements_by_id('some_id').click() 
+0

謝謝!你可以擴展爲什麼「刮取get請求返回的html不會產生你想要的結果」? – pir

+0

在大多數情況下,當您請求頁面時,並未加載完整的HTML,而是在初始加載呈現完整頁面後由瀏覽器創建額外的XHR或JavaScript請求,您可以使用開發工具 - >網絡,(在Chrome中你可以按f12),打開網頁後的第一個響應是你在使用requests.get時通常會得到的結果,並且你可以觀察到之後還有多少請求被提交... – SEDaradji

+0

好的,謝謝。爲什麼不能請求只抓取最後一個請求?服務器如何能夠從Selenium中分辨出​​來? – pir