bs4从<tags>列表中以<span>或<b>提取文本并将其保存在excel

时间:2018-09-12 08:58:19

标签: python pandas selenium beautifulsoup

我是bs4的新手,我正在寻找一种从页面中提取文本的方法,然后将其添加到Excel文件中,然后转到下一页,最后将新文本添加到已创建的Excel文件中。 这是我的结果

from selenium import webdriver
import scrapy
import datetime
import selenium
from bs4 import BeautifulSoup
import pandas as pd

geckodriver = "#here lies the path#"
options = webdriver.FirefoxOptions()
options.add_argument('-headless')

driver = webdriver.Firefox(executable_path=geckodriver, 

firefox_options=options)
link= "a result page from booking such as [this][1]"
driver.get(link)
pageSource = driver.page_source
bs = BeautifulSoup(pageSource, 'html.parser')
HotelNames = bs.select('.sr-hotel__name')
HotelScores = bs.select('.review-score-badge')
HotelPrices = prezziHotel = bs.findAll("b")

列表类似于此打印

print(HotelNames)
[<span class="sr-hotel__name " data-et-click="
customGoal:NAFLWCAHUJMDDWEYcZbBJOTXNORe:1
">
Residence Adam's Apple
</span>, <span class="sr-hotel__name " data-et-click="
customGoal:NAFLWCAHUJMDDWEYcZbBJOTXNORe:1
">
La Luna
</span>, <span class="sr-hotel__name " data-et-click="
">
Hotel Astor
</span>,

使用

HotelNames = HotelNames.get_text()

或提取出现以下错误

---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-33-01e95302c548> in <module>()
----> 1 nomeHotel = nomiHotel.getText()

AttributeError: 'list' object has no attribute 'get_text'

我个人不知道该怎么办。我得到的唯一结果是带有或标签的列表。如果我只能获取所需的文本(所有酒店的名称,所有酒店的等级和价格显示),则可以将其添加到Excel文件中。

对于Excel部分,我将执行以下代码

workbook = xlsxwriter.Workbook('Hotels.xlsx')
worksheet = workbook.add_worksheet()
rowName = 1
rowScore=1
rowPrice=1
col = 0
for name in (HotelNames):
    worksheet.write(rowName, 0, name)
    rowName += 1
for score in (HotelScores):
    worksheet.write(rowScore, 0, name)
    rowScore += 1
for price in (HotelPrices):
    worksheet.write(rowPrice, 0, name)
    rowPrice += 1

感谢所有帮助!

借助于Sarthak NegiAndersson的帮助,问题的第一部分得以解决 以下代码已使用并有效

i=0
HotelListNameWithoutTags = []
for name in HotelNames:
        HotelListNameWithoutTags.append(HotelNames[i].get_text())
        i=i+1
print(HotelListNameWithoutTags)
for name in HotelListNameWithoutTags:
    print(name)

但其他代码也起作用

HotelNames = [name.get_text() for name in HotelNames]

现在,此提取还有第二个小问题。两种情况下的结果都类似于以下输出:

Hotel Atlas


Residence Adam's Apple

当我打印一行时会发生这种情况。当我打印HotelListNameWithoutTags时,将显示以下输出:

['\nHotel Atlas\n', "\nResidence Adam's Apple\n",

Martin Evans帮助提供了以下代码

HotelNames = [name.replace('\ n','')作为酒店名称中的名称]

现在我有这个项目的最后一部分。 I)必须使用由带有href和文本的标记形成的网站中的导航栏来更改页面。非常“嵌套”的问题

<div class="bui-pagination results-paging">
     <div class="bui-pagination__nav">
          <ul class="bui-pagination__list">
               <li class="bui-pagination__pages">
                    <ul class="bui-pagination__list">
                         <li class="bui-pagination__item bui-pagination__item--active sr_pagination_item current">
                              <a class="bui-pagination__link sr_pagination_link" href="link">1</a>
</closing tags>

如何获取href或标记中的文本(在select中使用类的名称根本不起作用。页面中有很多内容,因此我也不能使用find_All方法)

1 个答案:

答案 0 :(得分:0)

最后,用于更改页面的解决方案是发现那里将有多少个页面。然后,创建一个列表,其中包含要搜索的页面,每次都刮所有数据。 以下是创建要抓取链接的列表的示例:

driver.get(link)
pages= bs.find_all("span","bui-pagination__info") 
for page in pages:
    page= page.get_text()

在这一部分中,我查找单个页面中有多少个元素。有时可以是10个元素,但有时可以是20、30甚至50。所以我不知道我必须写哪个数字。

page= page[-2:] #I need only the number in my case
page= int(pagina) #I need to be integer

links = bs.find_all("a", "bui-pagination__link sr_pagination_link")

linkNumber=[]
for l in links:
    l = l.get_text()
    linkNumber.append(l)

通过这种方式,我可以获得可以与硒一起使用的链接,还具有返回的页面数。我需要找到最后一页的“数字”。

ultimoNumeroLink = linkNumero[-1]
ultimoNumeroLink = int(ultimoNumeroLink)

numeroMassimoElementi = ultimoNumeroLink * pagina

使用最后的乘法,我可以找到我的研究中有多少个元素。