【发布时间】:2019-08-23 18:47:02
【问题描述】:
我用 python 编写了一个脚本来从网页的登录页面中抓取不同 retaurants 的 name、address 和 phone 并解析每个餐厅的 author 和 review内页。
我想在
get_additional_info(link)函数中使用yield生成结果,但在get_links(link)函数中与其他结果一起打印。
到目前为止我已经写了:
import requests
from bs4 import BeautifulSoup
from urllib.parse import urljoin
url = "https://www.yellowpages.com/search?search_terms=restaurant&geo_location_terms=San+Francisco%2C+CA"
base = "https://www.yellowpages.com"
def get_links(link):
res = requests.get(link,headers={'User-Agent':'Mozilla/5.0'})
soup = BeautifulSoup(res.text,"lxml")
for item in soup.select(".v-card"):
inner_link = item.select_one("a.business-name")
author,review = get_additional_info(urljoin(base,inner_link.get('href')))
title = inner_link.text
address = item.select_one("p.adr").get_text(strip=True)
phone = item.select_one(".phone").text
yield title,address,phone,author,review
def get_additional_info(link):
res = requests.get(link,headers={'User-Agent':'Mozilla/5.0'})
soup = BeautifulSoup(res.text,"lxml")
for elem in soup.select("article[class='clearfix']"):
try:
author = elem.select_one(".review-info a.author").text
except AttributeError: author = ""
try:
review = elem.select_one(".review-response > p").text
except AttributeError: review = ""
yield author, review
if __name__ == '__main__':
for item in get_links(url):
print(item)
如果我运行上面的脚本,它会抛出以下指向author,review = get_additional_info(urljoin(base,inner_link.get('href')))行的错误:
Traceback (most recent call last):
File "C:\Users\WCS\AppData\Local\Programs\Python\Python37-32\demo.py", line 36, in <module>
for item in get_links(url):
File "C:\Users\WCS\AppData\Local\Programs\Python\Python37-32\demo.py", line 14, in get_links
author,review = get_additional_info(urljoin(base,inner_link.get('href')))
ValueError: too many values to unpack (expected 2)
我希望抓取的所有字段都已正确定义(选择器)。
这就是the output我追求的方式:
PS 我希望坚持我已经尝试过的方式,这意味着我不想解析内页中的所有内容,因为这些数据对我来说毫无用处。
【问题讨论】:
-
get_additional_info()函数返回一个生成器;您必须使用此生成器才能获取项目,或者如果您不需要生成器,则更改函数以返回这些项目。 -
我可以在
get_additional_info()函数中返回所有这些项目并在get_links(link)中打印相同的内容吗?如果我按原样返回值,该函数将只记住最后一次迭代。 -
嗯,您可以将所有项目添加到列表中,但可以避免。为了打开生成器的包装,您必须知道它将返回多少个项目,这在这种情况下可能是不可能的。相反,您可以做的是遍历生成器并解压缩每个项目,就像在 Andrej 的回答中所做的那样。
-
非常感谢@t.m.adam 先生。这是我需要知道的。
标签: python python-3.x web-scraping