Как добавить эти данные в базу данных в scraperwiki
import scraperwiki
import urllib2, lxml.etree
url = 'http://eci.nic.in/eci_main/statisticalreports/SE_1998/StatisticalReport-DEL98.pdf'
pdfdata = urllib2.urlopen(url).read()
xmldata = scraperwiki.pdftoxml(pdfdata)
root = lxml.etree.fromstring(xmldata)
# how many pages in PDF
pages = list(root)
print "There are",len(pages),"pages"
#from page 86 to 107
for page in pages[86:107]:
for el in page:
data = {}
if el.tag == "text":
if int(el.attrib['left']) < 215: data = { 'Rank': el.text }
elif int(el.attrib['left']) < 230: data['Name'] = el.text
elif int(el.attrib['left']) < 592: data['Sex'] = el.text
elif int(el.attrib['left']) < 624: data['Party'] = el.text
elif int(el.attrib['left']) < 750: data['Votes'] = el.text
elif int(el.attrib['left']) < 801: data['Percentage'] = el.text
print data
Теперь мне интересно, как сохранить эти данные в базе данных в scraperwiki
, Я пробовал несколько команд, таких как
scraperwiki.sqlite.save(unique_keys=[], table_name='ecidata1998', data=data)
но они не дают мне требуемого результата при проверке набора данных. Что-то не так с кодом или последним утверждением. Пожалуйста помоги. Новое в программировании на Python и Scraperwiki.
1 ответ
Есть несколько проблем с вашим кодом.
Во-первых, условия, которые вы установили для извлечения другого содержимого из PDF, должны быть более ограниченными и точными (например, if int(el.attrib['left']) < 215
вытянет любой текст, который имеет левую позицию менее 215 пикселей, что относится к другому контенту на просматриваемых страницах PDF, например к тексту "Постоянная группа").
Во-вторых, вам нужен способ проверить, когда у вас есть все данные для этой строки и вы можете перейти к следующей. (Вы можете попытаться вытащить данные по строкам, но я просто обнаружил, что проще получать данные из каждого поля по очереди и создавать новую строку, когда у меня есть все данные для этой строки.)
(Относительно того, почему scraperwiki.sqlite.save
не работал, вероятно, потому что у вас были строки с пустыми значениями, но ваши данные в том виде, в котором они были, в любом случае были неверны.)
Это работает для меня:
import scraperwiki
import urllib2
import lxml.etree
def create_blank_row():
""" Create an empty candidate data dictionary. """
return {'Rank': None,
'Name': None,
'Sex': None,
'Party': None,
'Votes': None,
'Percentage': None}
def row_is_filled(dictionary):
""" Return True if all values of dictionary are filled; False if not. """
for item in dictionary.values():
if not item:
return False
return True
def main():
url = ('http://eci.nic.in/eci_main/statisticalreports'
'/SE_1998/StatisticalReport-DEL98.pdf')
pdfdata = urllib2.urlopen(url).read()
xmldata = scraperwiki.pdftoxml(pdfdata)
root = lxml.etree.fromstring(xmldata)
# how many pages in PDF
pages = list(root)
print "There are", len(pages), "pages"
output_data = []
candidate_data = create_blank_row()
#from page 86 to 107
for page in pages[86:107]:
for el in page:
if el.tag == "text":
if 206 < int(el.attrib['left']) <= 214:
# There are some None values here which we want to ignore.
if el.text:
candidate_data['Rank'] = el.text
if int(el.attrib['left']) == 222:
# Also removes ". " from start of names.
candidate_data['Name'] = el.text[2:]
if int(el.attrib['left']) == 591:
candidate_data['Sex'] = el.text
if int(el.attrib['left']) == 622:
candidate_data['Party'] = el.text
if 725 < int(el.attrib['left']) <= 753:
candidate_data['Votes'] = el.text
if 790 < int(el.attrib['left']) < 801:
candidate_data['Percentage'] = el.text
if row_is_filled(candidate_data):
output_data.append(candidate_data)
candidate_data = create_blank_row()
# Collect candidate data into a list then add to SQL database.
# Calls to this SQL write function slow, so minimise how many times we do.
scraperwiki.sqlite.save(unique_keys=['Rank', 'Name', 'Sex', 'Party',
'Votes'],
table_name='ecidata1998',
data=output_data)
if __name__ == '__main__':
main()