【问题标题】:Go through to original URL on social media management websites访问社交媒体管理网站上的原始 URL
【发布时间】:2017-11-23 07:49:45
【问题描述】:

我正在将网页抓取作为学术项目的一部分,在该项目中,所有链接都必须指向实际内容,这一点很重要。令人讨厌的是,“社交媒体管理”网站存在一些重要的错误案例,用户会在其中发布链接以检测谁点击了它们。

例如,考虑this link on linkis.com,它链接到 http:// + bit.ly + /1P1xh9J(由于 SO 发布限制,分隔链接),它又链接到 http://conservatives4palin.com。由于linkis.com 的原始链接不会自动向前重定向,因此会出现此问题。相反,用户必须单击右上角的叉号才能转到原始 URL。

此外,似乎有不同的变化(参见例如linkis.com link 2,其中十字位于网站的左下角)。这是我发现的仅有的两种变体,但可能还有更多。请注意,我使用的网络爬虫与this one 非常相似。进入实际链接的功能不需要随着时间的推移保持稳定/正常运行,因为这是一个一次性的学术项目。

如何自动转到原始 URL?最好的方法是设计一个找到相关链接的正则表达式吗?

【问题讨论】:

  • 没时间写答案,但寻找“unshorten URL python”可能会给你提示

标签: python regex hyperlink web-scraping


【解决方案1】:

在许多情况下,您将不得不使用浏览器自动化来抓取使用 javascript 生成其内容的网页,抓取 get 请求返回的 html 不会产生您想要的结果,您有两种选择:

  • 尝试绕过所有额外的 javascript 请求来获取您想要的内容,这可能非常耗时。
  • 使用浏览器自动化,它可以让您打开一个真正的浏览器并自动化其任务,您可以使用 Selenium 来实现。

我多年来一直在开发机器人和爬虫,除非您请求的网页不严重依赖 javascript,否则您应该使用 selenium 之类的东西。

这里有一些代码可以帮助您开始使用 selenium:

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()

【讨论】:

  • 谢谢!您能否详细说明为什么“抓取 get 请求返回的 html 不会产生您想要的结果”?
  • 在大多数情况下,当您请求页面时不会加载完整的 HTML,而是在初始加载后由浏览器发出额外的 XHR 或 javascript 请求以呈现整个页面,您可以使用任何浏览器下开发者工具->网络,(chrome中可以按f12),打开网页后的第一个响应是你一般使用requests.get时得到的,你可以观察之后又发出了多少请求...
  • 好的,谢谢。为什么请求不能只获取最后一个请求?服务器如何将它与 Selenium 区分开来?
  • 服务器一般不能(在大多数情况下至少..),你必须了解这个过程。使用真正的浏览器,当您请求页面时,结果中的脚本将被执行,当它们被执行时,它们可能会执行其他请求,但是使用 requests.get,脚本仍将被下载,仅此而已,他们基本上只是一个文本,您必须使用真正的浏览器来执行这些脚本,或者以艰难的方式执行,检查初始加载后发出的所有附加请求,然后尝试模拟它们,这通常比看起来更困难跨度>
【解决方案2】:

网站遵循的常见架构是将网站显示为 iframe。示例代码适用于这两种情况。

为了获得最终 URL,您可以执行以下操作:

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)

【讨论】:

  • 这看起来更健壮。你试过这个吗?如果它一直有效,我很乐意给你赏金。
  • 我在几个随机链接上尝试过。您可以使用您编写的代码将其插入。看看它是否有效。
  • 您知道是否有任何网站对其他类型的推荐使用相同的代码?例如,我不想捕捉嵌入的视频等。我只需要捕捉时间,整个页面是从其他地方嵌入的。
  • 你可以试试stumbleupon。你需要修改它以匹配他们的 xpath。
  • 它不适用于另一个社交媒体网站,paper.li:paper.li/GreenFraud/… 你能给我建议如何让它也适用于这个网站吗?
【解决方案3】:

根据您提供的两个网站,我认为您可以尝试以下代码来获取原始网址,因为它们都隐藏在 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

【讨论】:

  • 您的代码不起作用,import 语句丢失,即使添加了它们,仍然无法正常工作
  • 我添加了导入语句。它似乎在我的环境中工作。你是什么意思不工作?是否出现任何代码错误或无法获取链接?
【解决方案4】:

假设你能够获取 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 现在将是原始位链接的字符串!

【讨论】:

    【解决方案5】:

    试试下面的代码:

    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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-06-11
      • 2023-03-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多