【问题标题】:Web Scraping with Python, Beautiful Soup, and Selenium not working使用 Python、Beautiful Soup 和 Selenium 进行 Web 抓取不起作用
【发布时间】:2018-04-20 17:14:42
【问题描述】:

我正在做一个 Python 练习,它要求我通过网络抓取从 Google 新闻网站获取头条新闻并打印到控制台。 当我这样做时,我只是使用 Beautiful Soup 库来检索新闻。那是我的代码:

import bs4
from bs4 import BeautifulSoup
import urllib.request

news_url = "https://news.google.com/news/rss";
URLObject = urllib.request.urlopen(news_url);
xml_page = URLObject.read();
URLObject.close();

soup_page = BeautifulSoup(xml_page,"html.parser");
news_list = soup_page.findAll("item");

for news in news_list:
  print(news.title.text);
  print(news.link.text);
  print(news.pubDate.text);
  print("-"*60);

但是由于不打印“链接”和“pubDate”,它一直给我错误。经过一番研究,我在 Stack Overflow 上看到了一些答案,他们说,由于网站使用 Javascript,除了 Beautiful Soup 之外,还应该使用 Selenium 包。 尽管不了解 Selenium 的真正工作原理,但我将代码更新如下:

from bs4 import BeautifulSoup
from selenium import webdriver
import urllib.request

driver = webdriver.Chrome("C:/Users/mauricio/Downloads/chromedriver");
driver.maximize_window();
driver.get("https://news.google.com/news/rss");
content = driver.page_source.encode("utf-8").strip();
soup = BeautifulSoup(content, "html.parser");
news_list = soup.findAll("item");

print(news_list);

for news in news_list:
  print(news.title.text);
  print(news.link.text);
  print(news.pubDate.text);
  print("-"*60);

但是,当我运行它时,会打开一个空白浏览器页面,并将其打印到控制台:

 raise exception_class(message, screen, stacktrace)
selenium.common.exceptions.WebDriverException: Message: unknown error: Chrome failed to start: crashed
  (Driver info: chromedriver=2.38.551601 (edb21f07fc70e9027c746edd3201443e011a61ed),platform=Windows NT 6.3.9600 x86_64)

【问题讨论】:

  • 我相信您拥有的链接(带有/rss)是一个 XML 文件,因此其中没有使用 javascript
  • 那么,如何让“news.link.text”和“news.pubDate.text”同时出现在我的输出中?当我只使用 Beautiful Soup 打印它们时,“news.title.text”打印正常,链接打印一个新行,而 pub date 是一个例外,因为它返回 None 类型,我在其中使用了“.text”。跨度>

标签: python selenium web-scraping beautifulsoup


【解决方案1】:

我刚刚尝试过,以下代码对我有用。 items = 线太糟糕了,提前道歉。但现在它可以工作了......

编辑 刚刚更新了sn-p,你可以使用ElementTree.iter('tag')来遍历所有带有tag的节点:

import urllib.request
import xml.etree.ElementTree

news_url = "https://news.google.com/news/rss"
with urllib.request.urlopen(news_url) as page:
    xml_page = page.read()

# Parse XML page
e = xml.etree.ElementTree.fromstring(xml_page)

# Get the item list
for it in e.iter('item'):
    print(it.find('title').text)
    print(it.find('link').text)
    print(it.find('pubDate').text, '\n')

EDIT2:讨论用于抓取的库的个人偏好
就我个人而言,对于我必须在其中做东西交互式/动态页面(单击此处,填写表格,获取结果,...):我使用selenium,而且通常我不需要使用bs4,因为您可以直接使用selenium 来查找和解析您要查找的网络的特定节点。

我将bs4requests 结合使用(而不是urllib.request)在我不想安装整个网络驱动程序的项目中解析更多静态网页。 p>

使用urllib.request 并没有错,但是requests(请参阅此处以获取docs)是目前最好的python 包之一(在我看来),它是一个很好的例子,说明了如何创建一个简单而强大的 API。

【讨论】:

  • 现在对我有用。我以前没有听说过'xml.etree.ElementTree'。它是一种更可靠的网页抓取方式,而不是单独的 Beautiful Soup 或 Beautiful Soup + Selenium?提前致谢。
  • ElementTree(或 python2 的 cElementTree)在解析 XML 方面通常比几乎任何其他 (python) 选项都要好一些。关于python中XML解析的简要比较见here
  • @MauriceFigueiredo 我添加了第二个编辑,并简要讨论了我个人对抓取库的偏好
  • 那太好了,WillMonge。谢谢。
【解决方案2】:

只需将BeautifulSouprequests 一起使用。

from bs4 import BeautifulSoup
import requests

r = requests.get('https://news.google.com/news/rss')
soup = BeautifulSoup(r.text, 'xml')
news_list = soup.find_all('item')

# do whatever you need with news_list

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-01-09
    • 1970-01-01
    • 2021-04-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-20
    • 1970-01-01
    相关资源
    最近更新 更多