【问题标题】:It is not possible to parse a part of a webpage that is visible when open with browser无法解析使用浏览器打开时可见的网页部分
【发布时间】:2013-12-21 17:43:28
【问题描述】:

我在解析网页Herald Sun 以从中获取 rss 列表时遇到了这个奇怪的问题。当我在浏览器中查看网页时,我可以看到带有标题的链接。但是,当我使用 Python 和 Beautiful Soup 解析页面时,响应中甚至没有我想要解析的部分。

hdr = {'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9) AppleWebKit/537.71 (KHTML, like Gecko) Version/7.0 Safari/537.71',
               'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
               'Accept-Charset': 'ISO-8859-1,utf-8;q=0.7,*;q=0.3',
               'Accept-Encoding': 'none',
               'Accept-Language': 'en-US,en;q=0.8',
               'Connection': 'keep-alive'}

req = urllib.request.Request("http://www.heraldsun.com.au/help/rss", headers=hdr)

try:
    page = urllib.request.urlopen(req)
except urllib.error.HTTPError as e:
    print(e.fp.read())

html_doc = page.read()

f = open("Temp/original.html", 'w')
f.write(html_doc.decode('utf-8'))

你可以查看的写入文件,里面没有结果,所以很明显,Beautiful Soup 与这里无关。

我想知道,网页如何启用这种保护以及如何克服它?谢谢,

【问题讨论】:

    标签: python parsing html-parsing beautifulsoup urllib


    【解决方案1】:

    用于商业用途,请先阅读服务条款

    服务器知道的关于谁发出这个请求的信息真的不多。 IP、User-Agent 或 Cookie... 有时 urllib2 不会抓取 JavaScript 生成的信息。

    是否使用 JavaScript?

    (1)您需要打开chrome开发者并禁用缓存和Javascript以确保您仍然可以看到您想要的信息。如果您看不到那里的信息,则必须使用一些支持 Javascript 的工具,例如 Selenium 或 PhantomJS。

    但是,在这种情况下,您的网站看起来并不那么复杂。

    用户代理?饼干? (2) 然后问题就出在调优 User-Agent 或 Cookies 上。正如您之前尝试过的那样,用户代理似乎还不够。然后它将是 cookie 将发挥作用。

    如您所见,第一个页面调用实际上返回暂时不可用,您需要点击带有200返回码的rss HTML。你只需要从那里复制用户代理和 cookie 就可以了。

    这里是如何使用 urllib2 添加 cookie 的代码

    import urllib2, bs4, re
    
    opener = urllib2.build_opener()
    opener.addheaders = [("User-Agent","Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.57 Safari/537.36")]
    # I omitted the cookie here and you need to copy and paste your own
    opener.addheaders.append(('Cookie', 'act-bg-i...eat_uuniq=1; criteo=; pl=true'))
    soup = bs4.BeautifulSoup(opener.open("http://www.heraldsun.com.au/help/rss"))
    div = soup.find('div', {"id":"content-2"}).find('div', {"class":"group-content"})
    
    for a in div.find_all('a'):
        try:
            if 'feeds.news' in a['href']:
                print a 
        except:
            pass
    

    以下是输出:

    <a href="http://feeds.news.com.au/heraldsun/rss/heraldsun_news_breakingnews_2800.xml">Breaking News</a>
    <a href="http://feeds.news.com.au/heraldsun/rss/heraldsun_news_topstories_2803.xml">Top Stories</a>
    <a href="http://feeds.news.com.au/heraldsun/rss/heraldsun_news_worldnews_2793.xml">World News</a>
    <a href="http://feeds.news.com.au/heraldsun/rss/heraldsun_news_morenews_2794.xml">Victoria and National News</a>
    <a href="http://feeds.news.com.au/heraldsun/rss/heraldsun_news_sport_2789.xml">Sport News</a>
    ...
    

    【讨论】:

      【解决方案2】:

      网站很可能会提供不同的内容,具体取决于标题中的User-Agent 字符串。例如,网站通常会针对移动浏览器执行此操作。

      由于您没有指定一个,urllib 将使用其默认值:

      默认情况下,URLopener 类发送一个 urllib/VVV 的 User-Agent 头,其中 VVV 是 urllib 版本号。

      您可以按照advice in this question 尝试欺骗常见的用户代理字符串。见What's My User Agent?

      【讨论】:

      • 事实上,我确实使用了用户代理,让我编辑问题,因为当我复制代码时,我删除了那部分。
      • 叹息...这就是为什么发布您的实际代码的好理由。
      • 我更新了代码,还是有这个错误。不知道其他元素有没有影响。
      猜你喜欢
      • 2016-01-09
      • 1970-01-01
      • 1970-01-01
      • 2014-10-23
      • 1970-01-01
      • 2016-07-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多