BeautifulSoup 不会使用 .find_all('a') 抓取页面中的所有锚标记。我忽略了啥吗?
Posted
技术标签:
【中文标题】BeautifulSoup 不会使用 .find_all(\'a\') 抓取页面中的所有锚标记。我忽略了啥吗?【英文标题】:BeautifulSoup is not scraping ALL anchor tags in a page with .find_all('a'). Am I overlooking something?BeautifulSoup 不会使用 .find_all('a') 抓取页面中的所有锚标记。我忽略了什么吗? 【发布时间】:2014-02-06 09:13:42 【问题描述】:好的,所以在终端中,在导入和制作必要的对象之后——我输入:
for links in soup.find_all('a'):
print(links.get('href'))
它给了我***页面上的所有链接(大约 250 个)。没问题。
但是,在我正在编写的程序中,我只收到大约 60 个链接(这是在抓取同一个***页面),而我得到的那些链接大多一文不值。我仔细检查了我的初始化是否完全相同——唯一的区别是变量的名称。作为参考,这是我设置 BS4 对象并获取所需页面的函数:
def get_site(hyperLink):
userSite = urllib3.PoolManager()
siteData = userSite.request("GET", hyperLink)
bsd = BeautifulSoup(siteData.data)
return bsd
稍后,我抓取这些元素并将它们附加到一个列表中,然后我将对其进行操作:
def find_urls(bsd, urls, currentNetloc):
for links in bsd.find_all('a'):
urls.append(links.get('href'))
return urls
其他相关信息:
我使用的是 Python 3.3 我正在使用 urllib3、BeautifulSoup 4 和 urlparse(来自 urllib) 我在 PyCharm 工作(用于实际程序) 如果重要,请使用 Lubuntu。在运行 python3 的命令行实例并导入“sys”后,我输入并收到:
$ sys.executable
'/usr/bin/python3'
$ sys.path
['', '/usr/local/lib/python3.3/dist-packages/setuptools-1.1.5-py3.3.egg', '/usr/local/lib/python3.3/dist-packages/pip-1.4.1-py3.3.egg', '/usr/local/lib/python3.3/dist-packages/beautifulsoup4-4.3.2-py3.3.egg', '/usr/lib/python3.3', '/usr/lib/python3.3/plat-i386-linux-gnu', '/usr/lib/python3.3/lib-dynload', '/usr/local/lib/python3.3/dist-packages', '/usr/lib/python3/dist-packages']
在 Pycharm 项目中运行这些命令后,我收到了完全相同的结果,除了包含我的 pycharm 项目的目录包含在列表中。
【问题讨论】:
你能举一个你遇到这些问题的***页面的例子吗? 是的。例如,我用en.m.wikipedia.org/wiki/Lyceum_(Classical) 做了很多测试。我注意到在终端中我得到了一个链接,比如“古希腊”,但是在我的编码项目中,它几乎跳过了该页面内容中的所有链接,并且大部分都是通用链接。 再次检查:您在终端中使用的解释器和 PyCharm 使用的解释器是否相同? 当我通过 py charm 运行程序时,缺少抓取的 url。当我说通过终端正常运行它时,我的意思是一个实际的 Linux 终端。如果你的问题是关于哪个版本的 python,那么是的,我在命令行和 pycharm 中都使用了 python 3 对于简短和任何语法错误,我也很抱歉,我现在正在打电话。 【参考方案1】:我在网页抓取项目中遇到了很多问题;然而,BeautifulSoup 从来都不是罪魁祸首。
我高度怀疑你遇到了我在抓取***时遇到的同样问题。 Wikipedia 不喜欢我的用户代理,并且返回的页面与我请求的页面不同。尝试在您的代码中添加用户代理,例如
Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.36 (Khtml, like Gecko) Chrome/33.0.1750.146 Safari/537.36
您提到您使用的是 urllib3,因此您可以在 here 阅读有关如何使用自定义用户代理的信息。
此外,如果您想诊断您的问题,请尝试以下操作:在您说一切正常的终端中,添加一个额外的行 print len(html)
然后在您的程序中执行相同操作,看看您是否真的从同一页。
【讨论】:
【参考方案2】:这不是我的答案。我是从here 那里得到的,它以前对我有帮助。
from bs4 import BeautifulSoup
import csv
# Create .csv file with headers
f=csv.writer(open("nyccMeetings.csv","w"))
f.writerow(["Name", "Date", "Time", "Location", "Topic"])
# Use python html parser to avoid truncation
htmlContent = open("nyccMeetings.html")
soup = BeautifulSoup(htmlContent,"html.parser")
# Find each row
rows = soup.find_all('tr')
for tr in rows:
cols = tr.find_all('td') # Find each column
try:
names = cols[0].get_text().encode('utf-8')
date = cols[1].get_text().encode('utf-8')
time = cols[2].get_text().encode('utf-8')
location = cols[3].get_text().encode('utf-8')
topic = cols[4].get_text().encode('utf-8')
except:
continue
# Write to .csv file
f.writerow([names, date, time, location, topic])
我认为记录下我在编写此脚本时遇到的一些麻烦会很有用:
指定您的解析器。指定 BeautifulSoup 将用来解析 html 树形的 html 解析器的类型非常重要。我读入 Python 的 html 文件格式不正确,因此 BeautifulSoup 截断了 html,我只能访问大约四分之一的记录。通过告诉 BeautifulSoup 显式使用内置的 Python html 解析器,我能够避免这个问题并检索所有记录。
编码为 UTF-8。 get_text() 在对 html 标签内的文本进行编码时遇到了一些问题。因此,我无法将数据写入逗号分隔的文件。通过明确告诉程序编码为 UTF-8,我们完全避免了这个问题。
【讨论】:
请在这里回答问题。链接可能会失效。以上是关于BeautifulSoup 不会使用 .find_all('a') 抓取页面中的所有锚标记。我忽略了啥吗?的主要内容,如果未能解决你的问题,请参考以下文章
Python笔记-BeautifulSoup中find_all的使用及str中trim()