Начинающий Python: считывает элементы в одном файле и использует их для изменения другого файла

#python #loops #iteration #writing

#python #циклы #итерация

Вопрос:

Я экономист без опыта программирования. Я пытаюсь научиться использовать Python, потому что мне сказали, что он очень эффективен для анализа данных с веб-сайтов. На данный момент я застрял со следующим кодом, и я был бы чрезвычайно благодарен за любое предложение.

Прежде всего, я написал код для анализа данных из этой таблицы:

http://www.webifel.it/sifl/Tavola07.asp?comune=MILANOamp;cod_istat=15146

Код, который я написал, следующий:

 #!/usr/bin/env python

from mechanize import Browser
from BeautifulSoup import BeautifulSoup
import urllib2, os

def extract(soup):
table = soup.find("table", cellspacing=2)
for row in table.findAll('tr')[2:]:
        col = row.findAll('td')
        year = col[0].div.b.font.string
        detrazione = col[1].div.b.font.string
        ordinaria = col[2].div.b.font.string
        principale = col[3].div.b.font.string
        scopo = col[4].div.b.font.string
        record = (year, detrazione, ordinaria, principale, scopo)
        print >> outfile, "|".join(record)



outfile = open("milano.txt", "w")
br = Browser()
br.set_handle_robots(False)
url = "http://www.webifel.it/sifl/Tavola07.asp?comune=MILANOamp;cod_istat=15146"
page1 = br.open(url)
html1 = page1.read()
soup1 = BeautifulSoup(html1)
extract(soup1)
outfile.close()
  

Код считывает таблицу, берет только ту информацию, которая мне нужна, и создает текстовый файл. Код довольно примитивный, но он выполняет свою работу.

Моя проблема начинается сейчас. URL, который я опубликовал выше, является лишь одним из примерно 200, с которых мне нужно проанализировать данные. Все URL-адреса различаются только двумя элементами. Используя предыдущий URL:

http://www.webifel.it/sifl/Tavola07.asp?comune=MILANOamp;cod_istat=15146

два элемента, которые однозначно идентифицируют эту страницу, — это MILANO (название города) и 15146 (бюрократический код).

Что я хотел сделать, так это, во-первых, создать файл с двумя столбцами:

  1. Сначала названия городов, которые мне нужны;
  2. Во втором бюрократические коды.

Затем я хотел создать цикл на python, который считывает каждую строку этого файла, корректно изменяет URL в моем коде и выполняет задачу синтаксического анализа отдельно для каждого города.

У вас есть какие-либо предложения о том, как действовать дальше? Заранее спасибо за любую помощь и предложения!

[Обновить]

Спасибо всем за полезные предложения. Я нашел ответ Томаса К. наиболее простым для реализации, учитывая мои знания Python. Однако у меня все еще есть проблемы. Я модифицировал код следующим образом:

 #!/usr/bin/env python

from mechanize import Browser
from BeautifulSoup import BeautifulSoup
import urllib2, os
import csv

def extract(soup):
table = soup.find("table", cellspacing=2)
for row in table.findAll('tr')[2:]:
        col = row.findAll('td')
        year = col[0].div.b.font.string
        detrazione = col[1].div.b.font.string
        ordinaria = col[2].div.b.font.string
        principale = col[3].div.b.font.string
        scopo = col[4].div.b.font.string
        record = (year, detrazione, ordinaria, principale, scopo)
        print >> outfile, "|".join(record)

citylist = csv.reader(open("citycodes.csv", "rU"), dialect = csv.excel)
for city in citylist:
outfile = open("%s.txt", "w") % city
br = Browser()
br.set_handle_robots(False)
url = "http://www.webifel.it/sifl/Tavola07.asp?comune=%samp;cod_istat=%s" % city
page1 = br.open(url)
html1 = page1.read()
soup1 = BeautifulSoup(html1)
extract(soup1)
outfile.close()
  

где citycodes.csv имеет следующий формат

 MILANO;12345
MODENA;67891
  

Я получаю следующую ошибку:

 Traceback (most recent call last):
File "modena2.py", line 25, in <module>
 outfile = open("%s.txt", "w") % city
TypeError: unsupported operand type(s) for %: 'file' and 'list'
  

Еще раз спасибо!

Комментарии:

1. Нужно ли также изменять выходной файл или все данные будут записаны в один файл. Исходя из вашего примера, я предполагаю, что вам также нужно изменить имя выходного файла, но я подумал, что все равно спрошу.

2. Да, именно. Я хочу отдельные текстовые файлы для каждого города. Я модифицировал код, следуя одному из ответов. Но у меня все еще есть проблемы.

3. попробуйте это: outfile = open("%s.txt" % city[0], "w")

Ответ №1:

Вам нужно исправить одну маленькую вещь:

Это:

 for city in citylist:
    outfile = open("%s.txt", "w") % city
#                                 ^^^^^^
  

Должно быть это:

 for city in citylist:
    outfile = open("%s.txt" % city, "w")
#                           ^^^^^^
  

Ответ №2:

Если файл в формате CSV, вы можете использовать csv для его чтения. Затем просто используйте urllib.urlencode() для генерации строки запроса и urlparse.urlunparse() для генерации полного URL.

Комментарии:

1. Большое спасибо за ваш ответ. К сожалению, из-за моего уровня знаний python мне действительно сложно применить эти инструменты к моей конкретной проблеме, начиная с официальной документации.

Ответ №3:

Нет необходимости создавать отдельный файл, вместо этого используйте словарь python, в котором есть взаимосвязь: город-> код.

Смотрите: http://docs.python.org/tutorial/datastructures.html#dictionaries

Комментарии:

1. Или просто список из двух кортежей: [("MILANO", "15146"),("ROMA","12345"),...] . Если вы создаете dict, вы все равно собираетесь вызывать .iteritems() только его.

Ответ №4:

Быстро и грязно:

 import csv
citylist = csv.reader(open("citylist.csv"))
for city in citylist:
    url = "http://www.webifel.it/sifl/Tavola07.asp?comune=%samp;cod_istat=%s" % city
    # open the page and extract the information
  

Предполагая, что у вас есть CSV-файл, выглядящий как:

 MILANO,15146
ROMA,12345
  

Существуют более мощные инструменты, такие urllib.urlencode() , как упоминал Игнасио. Но для этого они, вероятно, излишни.

P.S. Поздравляю: вы выполнили жесткую очистку данных из HTML. Цикл по списку — это самое простое.

Комментарии:

1. Большое спасибо. Я отредактировал вопрос, приняв во внимание ваши предложения. Однако у меня все еще есть проблемы! Еще раз спасибо!

Ответ №5:

Просто изучаю основы…

 #!/usr/bin/env python

from mechanize import Browser
from BeautifulSoup import BeautifulSoup
import urllib2, os

outfile = open("milano.txt", "w")

def extract(soup):
    global outfile
    table = soup.find("table", cellspacing=2)
    for row in table.findAll('tr')[2:]:
            col = row.findAll('td')
            year = col[0].div.b.font.string
            detrazione = col[1].div.b.font.string
            ordinaria = col[2].div.b.font.string
            principale = col[3].div.b.font.string
            scopo = col[4].div.b.font.string
            record = (year, detrazione, ordinaria, principale, scopo)
            print >> outfile, "|".join(record)



br = Browser()
br.set_handle_robots(False)

# fill in your cities here anyway like
ListOfCityCodePairs = [('MILANO', 15146)]

for (city, code) in ListOfCityCodePairs:
    url = "http://www.webifel.it/sifl/Tavola07.asp?comune=%samp;cod_istat=d" % (city, code)
    page1 = br.open(url)
    html1 = page1.read()
    soup1 = BeautifulSoup(html1)
    extract(soup1)

outfile.close()
  

Комментарии:

1. Большое спасибо. Сначала я попытаюсь прочитать пары (город, код) из файла csv. Если я не смогу решить проблемы, на которые я указал в отредактированной версии моего вопроса, я обязательно воспользуюсь вашим методом. Спасибо!