【问题标题】:How to save the string, one word per column in Python?如何在Python中保存字符串,每列一个单词?
【发布时间】:2015-10-05 02:42:12
【问题描述】:

我正在从目录中抓取按摩治疗师的姓名及其地址。整个字符串的地址都保存在 CSV 中的一列中,但每个治疗师的标题/姓名每列保存一个单词,超过 2 或 3 列。

我需要做什么才能将提取的字符串保存在一列中,就像保存地址一样? (前两行代码是页面中的示例 html,下一组代码是针对此元素的脚本的摘录)

<span class="name">
    <img src="/images/famt-placeholder-sm.jpg" class="thumb" alt="Tiffani D Abraham"> Tiffani D Abraham</span>


import mechanize
from lxml import html
import csv
import io
from time import sleep

def save_products (products, writer):

    for product in products:

        for price in product['prices']:
            writer.writerow([ product["title"].encode('utf-8') ])
            writer.writerow([ price["contact"].encode('utf-8') ])
            writer.writerow([ price["services"].encode('utf-8') ])

f_out = open('mtResult.csv', 'wb')
writer = csv.writer(f_out)

links = ["https://www.amtamassage.org/findamassage/results.html?match=exact&l=NY","https://www.amtamassage.org/findamassage/results.html?match=exact&l=NY&PageIndex=2&PageSize=10","https://www.amtamassage.org/findamassage/results.html?match=exact&l=NY&PageIndex=3&PageSize=10","https://www.amtamassage.org/findamassage/results.html?match=exact&l=NY&PageIndex=4&PageSize=10","https://www.amtamassage.org/findamassage/results.html?match=exact&l=NY&PageIndex=5&PageSize=10","https://www.amtamassage.org/findamassage/results.html?match=exact&l=NY&PageIndex=6&PageSize=10","https://www.amtamassage.org/findamassage/results.html?match=exact&l=NY&PageIndex=7&PageSize=10", "https://www.amtamassage.org/findamassage/results.html?match=exact&l=NY&PageIndex=8&PageSize=10", "https://www.amtamassage.org/findamassage/results.html?match=exact&l=NY&PageIndex=9&PageSize=10", "https://www.amtamassage.org/findamassage/results.html?match=exact&l=NY&PageIndex=10&PageSize=10" ]

br = mechanize.Browser()    

for link in links:

    print(link)
    r = br.open(link)

    content = r.read()

    products = []        
    tree = html.fromstring(content)        
    product_nodes = tree.xpath('//ul[@class="famt-results"]/li')

    for product_node in product_nodes:

        product = {}


        price_nodes = product_node.xpath('.//a')

        product['prices'] = []
        for price_node in price_nodes:

            price = {}
            try:
                product['title'] = product_node.xpath('.//span[1]/text()')[0]

            except:
                product['title'] = ""

            try:
                price['services'] = price_node.xpath('./span[2]/text()')[0]

            except:
                price['services'] = ""

            try:
                price['contact'] = price_node.xpath('./span[3]/text()')[0]

            except:
                price['contact'] = ""

            product['prices'].append(price)
        products.append(product)
    save_products(products, writer)

f_out.close() 

【问题讨论】:

  • 请将您的部分数据添加到您的问题中,这样会更容易理解您的意思。
  • @LetzerWille 这是我从中提取的页面:https://www.amtamassage.org/findamassage/results.html?match=exact&amp;l=NY - 生成的 csv 是每个治疗师 3 行,顺序从姓名、地址、专业递减。地址和专业只保存在 A 列中,但名称分布在 B、C 和 D 列中,每列一个单词。我现在已经发布了整个脚本。
  • 我意识到问题在于product["title"] 的数据是字符串而不是列表(与servicescontact 的数据不同,它们都是列表)。我知道我需要更改一些导致它期望列表而不是字符串的内容,但我不确定需要调整代码的哪一部分。

标签: python csv web-scraping


【解决方案1】:

如果这能解决您遇到的问题,我不肯定,但无论哪种方式,您都可能会感兴趣的一些改进和修改。

例如,由于每个链接都因页面索引而异,您可以轻松地循环访问链接,而不是将所有 50 个链接复制到一个列表中。每个页面的每个治疗师也有自己的索引,因此您还可以遍历 xpath 以获取每个治疗师的信息。

#import modules
import mechanize
from lxml import html
import csv
import io

#open browser
br = mechanize.Browser()

#create file headers
titles = ["NAME"]
services = ["TECHNIQUE(S)"]
contacts = ["CONTACT INFO"]

#loop through all 50 webpages for therapist data
for link_index in range(1,50):

    link = "https://www.amtamassage.org/findamassage/results.html?match=exact&l=NY&PageIndex=" + str(link_index) + "&PageSize=10"
    r = br.open(link)
    page = r.read()      
    tree = html.fromstring(page)        

    #loop through therapist data for each therapist per page
    for therapist_index in range(1,10):

        #store names
        title = tree.xpath('//*[@id="content"]/div[2]/ul[1]/li[' + str(therapist_index) + ']/a/span[1]/text()')
        titles.append(" ".join(title))

        #store techniques and convert to unicode
        service = tree.xpath('//*[@id="content"]/div[2]/ul[1]/li[' + str(therapist_index) + ']/a/span[2]/text()')
        try:
            services.append(service[0].encode("utf-8"))
        except:
            services.append(" ")

        #store contact info and convert to unicode
        contact = tree.xpath('//*[@id="content"]/div[2]/ul[1]/li[' + str(therapist_index) + ']/a/span[3]/text()')
        try:
            contacts.append(contact[0].encode("utf-8"))
        except:
            contacts.append(" ")

#open file to write to
f_out = open('mtResult.csv', 'wb')
writer = csv.writer(f_out)

#get rows in correct format
rows = zip(titles, services, contacts)

#write csv line by line
for row in rows:
    writer.writerow(row)
f_out.close()

该脚本会循环访问所提供网页上的所有 50 个链接,并且如果提供的话,它似乎正在抓取每位治疗师的所有相关信息。最后,它会将所有数据打印到 csv 中,所有数据都存储在“名称”、“技术”和“联系信息”的相应列下,如果这是您最初遇到的问题。

希望这会有所帮助!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-12-17
    • 2015-03-17
    • 1970-01-01
    • 2017-08-19
    相关资源
    最近更新 更多