2016-04-23 14 views
-1

Я пытаюсь очистить сайт и записать данные в файл CSV (успешно). Я столкнулся с двумя проблемами:Python TypeError: объект «NoneType» не является вызываемым

  1. Данные в CSV-файле сохраняются в ROWS не в столбцах.
  2. У сайта есть страницы, 1,2,3,4 ... Далее Я не могу просматривать все страницы, чтобы очистить данные. Данные списываются только с первой страницы.

Ошибка:

if last_link.startswith('Next'): 
TypeError: 'NoneType' object is not callable 

Код:

import requests 
import csv 
from bs4 import BeautifulSoup 

url = 'http://localhost:8088/wiki.html' 

response = requests.get(url) 
html = response.content 
soup = BeautifulSoup(html) 

table = soup.find('table', {'class' : 'tab_operator'}) 

list_of_rows = [] 
for rows in table.findAll('tr'): 
    list_of_cells = [] 
    for cell in rows.findAll('td'): 
     list_of_links = [] 
     for links in cell.findAll('a'): 
      text = links.text.replace(' ', '') 
      list_of_links.append(text) 
     list_of_rows.append(list_of_links) 

outfile = open('./outfile.csv', 'w') 
writer = csv.writer(outfile) 
writer.writerows(list_of_rows) 

try: 
    last_link = soup.find('table', {'id' : 'str_nav'}).find_all('a')[-1] 
    if last_link.startswith('Next'): 
     next_url_parts = urllib.parse.urlparse(last_link['href']) 
     url = urllib.parse.urlunparse((base_url_parts.scheme, base_url_parts.netloc, next_url_parts.path, next_url_parts.params, next_url_parts.query, next_url_parts.fragment)) 

except ValueError: 
    print("Oops! Try again...") 

Сайт код HTML пример:

### Numbers to scrape ### 

<table cellpadding="10" cellspacing="0" border="0" style="margin-top:20px;" class="tab_operator"> 
<tbody><tr> 
<td valign="top"> 
<a href="http://localhost:8088/wiki/9400000">9400000</a><br> 
<a href="http://localhost:8088/wiki/9400001">9400001</a><br> 
</td> 
</tr></tbody> 
</table> 

### Paging Sample Code: ### 

<div class="pstrnav" align="center"> 
<table cellpadding="0" cellspacing="2" border="0" id="str_nav"> 
<tbody> 
<tr> 
<td style="background-color:#f5f5f5;font-weight:bold;">1</td> 
<td><a href="http://localhost:8088/wiki/2">2</a></td> 
<td><a href="http://localhost:8088/wiki/3">3</a></td> 
<td><a href="http://localhost:8088/wiki/4">4</a></td> 
<td><a href="http://localhost:8088/wiki/2">Next &gt;&gt;</a></td> 
<td><a href="http://localhost:8088/wiki/100">Last</a></td> 
</tr> 
</tbody> 
</table> 
</div> 

ответ

0

last_link является объектом тега, не строка. BeautifulSoup обрабатывает любое имя атрибута в теге, который не является существующим атрибутом или методом, в качестве поиска тега вместо. Поскольку нет startswith тега в ссылке, что поиск возвращает None, и это то, что объект, который вы пытаетесь вызвать:

>>> last_link = soup.find('table', {'id' : 'str_nav'}).find_all('a')[-1] 
>>> last_link 
<a href="http://localhost:8088/wiki/100">Last</a> 
>>> last_link.startswith is None 
True 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
TypeError: 'NoneType' object is not callable 

Вы хотите проверить содержащийся текст вместо:

if last_link.get_text(strip=True).startswith('Next'): 

Использует Tag.get_text() method для доступа ко всему тексту в ссылке; использование этого метода работает, даже если в ссылке есть другие теги (например, <b> или <i>).

Вы, вероятно, хотите, чтобы искать непосредственно для Next ссылке здесь:

import re 

table = soup.select_one('table#str_nav') 
last_link = table.find('a', text=re.compile('^Next')) 

Регулярное выражение указывает, что только непосредственно содержал текст, начинающийся с Next позволяет a тег, чтобы соответствовать.

+0

сделал изменения как предложено ... 'table = soup.select_one ('table # str_nav') last_link = table.find ('a', text = re.compile ('^ Next')) if last_link .get_text (strip = True) .startswith ('Next'): '..... но все еще получаю сообщение об ошибке:' table = soup.select_one ('table # str_nav') TypeError: объект «NoneType» не является callable' – Overflow

+0

@Overflow: 'select_one' требует BeautifulSoup 4.4.0 или новее (выпущено около 6 месяцев назад, IIRC). –

+0

@Overflow: используйте 'table = soup.select ('table # str_nav') [0]', если ваша установка bs4 старше. –

Смежные вопросы