#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 (бюрократический код).
Что я хотел сделать, так это, во-первых, создать файл с двумя столбцами:
- Сначала названия городов, которые мне нужны;
- Во втором бюрократические коды.
Затем я хотел создать цикл на 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. Если я не смогу решить проблемы, на которые я указал в отредактированной версии моего вопроса, я обязательно воспользуюсь вашим методом. Спасибо!