将未找到的元素设置为Null / Empty而不是跳过它们

时间:2018-07-02 17:02:25

标签: python selenium

我想弄清楚如何将未找到的元素设置为null而不是跳过循环。在某些情况下,如果缺少“名称”,“标题”或“公司”,那么我想在csv中留空。我对python的了解有限,因此我真的可以使用一些帮助。

我已经拥有的问题是,如果引发异常,则该行将被完全跳过。什么是实现我所寻找的最佳方法?熊猫数据框会对此有所帮助吗?如果是这样,我应该怎么写?我应该以其他方式写给csv吗?

filename = "C:\\scrape.csv"
f = open(filename, "w")

headers = "Name, Company, Title\n"

f.write(headers)

names = []
for value in names:
#Search
browser.find_element_by_xpath("//*[@id='ctl09_FindFirstName']").send_keys(value)
browser.find_element_by_xpath("//*[@id='ctl11_FindContacts']").click()
try:
    for i in range(5):
        try:
            Name = browser.find_element_by_xpath("//*[@id='ctl11_DisplayName_"+str(i)+"']").text
            Company = browser.find_element_by_xpath("//*[@id='ctl11_CompanyNamePanel_"+str(i)+"']").text
            Title = browser.find_element_by_xpath("//*[@id='ctl11_CompanyTitlePanel_"+str(i)+"']").text

            f.write(Name.replace(",", "|") + "," + Company.replace(",", "|") + "," + Title.replace(",", "|") + "\n")

            #print("Name: " + browser.find_element_by_xpath("//*[@id='ctl11_DisplayName_"+str(i)+"']").text)
            #print("Company: " + browser.find_element_by_xpath("//*[@id='ctl11_CompanyNamePanel_"+str(i)+"']").text)
            #print("Title: " + browser.find_element_by_xpath("//*[@id='ctl11_CompanyTitlePanel_"+str(i)+"']").text)
        except NoSuchElementException:        
            continue                                                                                  
except NoSuchElementException:
    pass
f.close()

3 个答案:

答案 0 :(得分:3)

您可以使用find_element_by来代替find_elements_by。这样,它将创建找到的元素的列表,如果找不到匹配的元素而不是抛出 NoSuchElementException <,则会创建一个 列表。 / em>。

尝试一下:

browser.find_element_by_xpath("//*[@id='ctl09_FindFirstName']").send_keys(value)
browser.find_element_by_xpath("//*[@id='ctl11_FindContacts']").click()
for i in range(5):
    Name = browser.find_elements_by_xpath("//*[@id='ctl11_DisplayName_"+str(i)+"']").text
    Company = browser.find_elements_by_xpath("//*[@id='ctl11_CompanyNamePanel_"+str(i)+"']").text
    Title = browser.find_elements_by_xpath("//*[@id='ctl11_CompanyTitlePanel_"+str(i)+"']").text

    if not Name: name = "None"
    else: name = Name[0].text

    if not Company: company = "None"
    else: company = Company[0].text

    if not Title: title = "None"
    else: title = Title[0].text

    f.write(name.replace(",", "|") + "," + company.replace(",", "|") + "," + title.replace(",", "|") + "\n")                                                                             
f.close()

答案 1 :(得分:2)

您可以这样做:

filename = "C:\\scrape.csv"
f = open(filename, "w")

headers = "Name, Company, Title\n"

f.write(headers)

names = []
for value in names:
    #Search
    browser.find_element_by_xpath("//*[@id='ctl09_FindFirstName']").send_keys(value)
    browser.find_element_by_xpath("//*[@id='ctl11_FindContacts']").click()


    for i in range(5):
        Names = browser.find_elements_by_xpath("//*[@id='ctl11_DisplayName_" + str(i) + "']")
        if len(Names) == 0:
            name = 'Empty'
        else:
            name = Names[0].text

        Companys = browser.find_elements_by_xpath("//*[@id='ctl11_CompanyNamePanel_" + str(i) + "']")
        if len(Companys) == 0:
            company = 'Empty'
        else:
            company = Companys[0].text

        Titles = browser.find_elements_by_xpath("//*[@id='ctl11_CompanyTitlePanel_" + str(i) + "']")
        if len(Titles) == 0:
            title = 'Empty'
        else:
            title = Titles[0].text

        f.write(name.replace(",", "|") + "," + company.replace(",", "|") + "," + title.replace(",", "|") + "\n")

f.close()

如您所见,您不再需要try/catch。如果未找到任何元素,则该元素将设置为“空”字符串。 browser.find_elements...不会抛出NoSuchElementException

答案 2 :(得分:2)

其他答案已解决了跳过行的问题,但不包含有关问题所询问的有关熊猫的任何信息。

对于Pandas,您可能会使用数据框,而不是像以前那样将每一行写到文件中。然后,您可以使用to_csv()的数据框导出方法来获取数据。我个人使用this link引用了许多不同的方法来将数据放入数据框。

我要做的方法是将当前try块中的每个变量附加到由这些变量的所有实例组成的单独列表中。在此示例中,从三个空白列表开始

names_list = []
companies_list = []
titles_list = []

然后在循环中删除值

names_list.append(name)
companes_list.append(company)
titles_list.append(title)

然后我将tuple()的那些列表添加到一个名为data的大列表中,并创建一个名为labels的列表来保存列名。

names_tup = tuple(names_list)
companies_tup = tuple(companies_list)
titles_tup = tuple(titles_list)
data = [names_tup, companies_tup, titles_tup]
labels = ['name', 'company', 'title']

然后按照上面引用的链接将数据转换为数据框。

import pandas as pd
pd.DataFrame.from_records(data, columns=labels)

最后,将数据框另存为csv:

fileLocation = 'path\\to\\filename.csv'
df.to_csv(path_or_buf = fileLocation, sep=',')