【问题标题】:Combining Two Separate WebScraped lists in Python在 Python 中组合两个单独的 WebScraped 列表
【发布时间】:2017-10-17 13:55:50
【问题描述】:

我正在从汽车网站抓取数据以获取价格。现在,我正在通过创建两个单独的列表来解决这个问题;一个定价数据和另一个汽车型号。最终,我想获取每个列表并将两者连接在一起以创建一个 CSV。 我为解决这个问题而采取的具体步骤如下:

  1. 建立与网站的连接
  2. 创建两个空列表以将数据写入
  3. 从页面的每个部分选择正确的数据
  4. 遍历数据并将该数据存储到列表中(这是我遇到问题的地方)
  5. 最后,我要将这两个列表合并为一个 CSV。
from bs4 import BeautifulSoup
import urllib2

#1) establishing a connection to the website
wiki = "http://www.morong.com/used-inventory/index.htm?start=16&"
req = urllib2.Request(wiki)
page = urllib2.urlopen(req)
soup = BeautifulSoup(page, 'lxml')

#2) creating two empty lists to write the data into
valueHolder = []
nameHolder = []

#3) selecting the correct data from each part of the page 
value = soup.findAll("span", { "class" : "value" })

name = soup.findAll("a", {"class" : "url"})

#4) iterates over rows and turns each row into a text field
for row in value:
    valueholder = row.text

for row in name:
    nameHolder = row.text
print(valueholder)
print(nameHolder)

当我打印 valueHoldernameHolder 时,我只返回每个 for 循环的最后一行。如何打印所有值?

【问题讨论】:

    标签: python csv


    【解决方案1】:

    使用 zip() 函数连接这两个列表:

    value = [row.text for row in value]   
    name = [row.text for row in name]
    zipped_value_name = list(zip(value, name))
    
    for row in zipped_value_name:
        print(row)
    

    您也可以创建字典而不是列表dict_not_list = dict((zip(name, value))

    【讨论】:

    • 我正要回答这个问题。但我认为这是 OP 需要的
    【解决方案2】:

    您正在循环中重新分配 valueHoldernameHolder 标识符,而不是向列表中添加元素。试试这个:

    for row in value:
              valueHolder.append(row.text)    
         for row in name:
             nameHolder.append(row.text)
    

    要合并列表,您可以使用 map,例如 in

    combinations = list(map(lambda x,y: [x,y], nameHolder, valueHolder))
    

    【讨论】:

    • 恭喜,你刚刚重新发明了内置的zip()函数
    【解决方案3】:

    简单地说:

    for row in value:
        valueholder = row.text
        print(valueholder)
    
    for row in name:
        nameHolder = row.text
        print(nameHolder)
    

    【讨论】:

    • “官僚康拉德你在技术上是正确的......最好的正确。”
    【解决方案4】:

    您的问题来自循环中的 valueHoldernameHolder 变量的重新绑定(重新分配):

    # here you bind `valueHolder` to an empty list
    valueHolder = []
    value = soup.findAll("span", { "class" : "value" })
    for row in value:
        # here you rebind it to `row.text` (loosing the empty list)
        valueHolder = row.text
    

    您想要的是追加到列表中:

    valueHolder = []
    value = soup.findAll("span", { "class" : "value" })
    for row in value:
        valueHolder.append(row.text)
    

    要合并两个列表,您可以使用zip()

    result = zip(nameHolder, valueHolder) 
    

    这将创建一个(name, value) 元组列表。

    这就是说,而不是执行两个不同的查找/循环附加到两个不同的列表,你会更好地迭代父元素(源标记中同时包含“值”跨度和“名称”的元素链接)并建立一个(name, value)元组列表:

    results = []
    for item in soup.findAll("li", {"class":"item"}):
        value = soup.find("span", { "class" : "value" }).text
        name = soup.find("a", {"class" : "url"}).text
        results.append((name, value))
    

    这样您可以合理地确定名称和值将真正匹配,但您的解决方案可能不一定是这种情况。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-12-27
      • 2018-10-30
      • 2019-02-05
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多