lxml لا يعمل مع جانغو، سكرابيرويكي
-
20-12-2019 - |
سؤال
أنا أعمل على تطبيق Django الذي يمر عبر موقع الجمعية العامة في إلينوي لاستخراج بعض ملفات PDF.أثناء نشره على سطح المكتب، فإنه يعمل بشكل جيد حتى تنتهي مهلة urllib2.عندما أحاول النشر على خادم Bluehost الخاص بي، يظهر خطأ في الجزء lxml من الكود.سيكون موضع تقدير أي مساعدة.
import scraperwiki
from bs4 import BeautifulSoup
import urllib2
import lxml.etree
import re
from django.core.management.base import BaseCommand
from legi.models import Votes
class Command(BaseCommand):
def handle(self, *args, **options):
chmbrs =['http://www.ilga.gov/house/', 'http://www.ilga.gov/senate/']
for chmbr in chmbrs:
site = chmbr
url = urllib2.urlopen(site)
content = url.read()
soup = BeautifulSoup(content)
links = []
linkStats = []
x=0
y=0
table = soup.find('table', cellpadding=3)
for a in soup.findAll('a',href=True):
if re.findall('Bills', a['href']):
l = (site + a['href']+'&Primary=True')
links.append(str(l))
x+=1
print x
for link in links:
url = urllib2.urlopen(link)
content = url.read()
soup = BeautifulSoup(content)
table = soup.find('table', cellpadding=3)
for a in table.findAll('a',href=True):
if re.findall('BillStatus', a['href']):
linkStats.append(str('http://ilga.gov'+a['href']))
for linkStat in linkStats:
url = urllib2.urlopen(linkStat)
content = url.read()
soup = BeautifulSoup(content)
for a in soup.findAll('a',href=True):
if re.findall('votehistory', a['href']):
vl = 'http://ilga.gov/legislation/'+a['href']
url = urllib2.urlopen(vl)
content = url.read()
soup = BeautifulSoup(content)
for b in soup.findAll('a',href=True):
if re.findall('votehistory', b['href']):
llink = 'http://ilga.gov'+b['href']
try:
u = urllib2.urlopen(llink)
x = scraperwiki.pdftoxml(u.read())
root = lxml.etree.fromstring(x)
pages = list(root)
chamber = str()
for page in pages:
print "working_1"
for el in page:
print "working_2"
if el.tag == 'text':
if int(el.attrib['top']) == 168:
chamber = el.text
if re.findall("Senate Vote", chamber):
if int(el.attrib['top']) >= 203 and int(el.attrib['top']) < 231:
title = el.text
if (re.findall('House', title)):
title = (re.findall('[0-9]+', title))
title = "HB"+title[0]
elif (re.findall('Senate', title)):
title = (re.findall('[0-9]+', title))
title = "SB"+title[0]
if int(el.attrib['top']) >350 and int(el.attrib['top']) <650:
r = el.text
names = re.findall(r'[A-z-\u00F1]{3,}',r)
vs = re.findall(r'[A-Z]{1,2}\s',r)
for name in names:
legi = name
for vote in vs:
v = vote
if Votes.objects.filter(legislation=title).exists() == False:
c = Votes(legislation=title, legislator=legi, vote=v)
c.save()
print 'saved'
else:
print 'not saved'
elif int(el.attrib['top']) == 189:
chamber = el.text
if re.findall("HOUSE ROLL CALL", chamber):
if int(el.attrib['top']) > 200 and int(el.attrib['top']) <215:
title = el.text
if (re.findall('HOUSE', title)):
title = (re.findall('[0-9]+', title))
title = "HB"+title[0]
elif (re.findall('SENATE', title)):
title = (re.findall('[0-9]+', title))
title = "SB"+title[0]
if int(el.attrib['top']) >385 and int(el.attrib['top']) <1000:
r = el.text
names = re.findall(r'[A-z-\u00F1]{3,}',r)
votes = re.findall(r'[A-Z]{1,2}\s',r)
for name in names:
legi = name
for vote in votes:
v = vote
if Votes.objects.filter(legislation=title).exists() == False:
c = Votes(legislation=title, legislator=legi, vote=v)
c.save()
print 'saved'
else:
print 'not saved'
except:
pass
تحرير 1وهنا أثر الخطأ
Traceback (most recent call last):
File "manage.py", line 10, in <module>
execute_from_command_line(sys.argv)
File "/home7/maythirt/python27/lib/python2.7/site-packages/django/core/management/__init__.py", line 399, in execute_from_command_line
utility.execute()
File "/home7/maythirt/python27/lib/python2.7/site-packages/django/core/management/__init__.py", line 392, in execute
self.fetch_command(subcommand).run_from_argv(self.argv)
File "/home7/maythirt/python27/lib/python2.7/site-packages/django/core/management/base.py", line 242, in run_from_argv
self.execute(*args, **options.__dict__)
File "/home7/maythirt/python27/lib/python2.7/site-packages/django/core/management/base.py", line 285, in execute
output = self.handle(*args, **options)
File "/home7/maythirt/GAB/legi/management/commands/vote.py", line 51, in handle
root = lxml.etree.fromstring(x)
File "lxml.etree.pyx", line 3032, in lxml.etree.fromstring (src/lxml/lxml.etree.c:68121)
File "parser.pxi", line 1786, in lxml.etree._parseMemoryDocument (src/lxml/lxml.etree.c:102470)
File "parser.pxi", line 1674, in lxml.etree._parseDoc (src/lxml/lxml.etree.c:101299)
File "parser.pxi", line 1074, in lxml.etree._BaseParser._parseDoc (src/lxml/lxml.etree.c:96481)
File "parser.pxi", line 582, in lxml.etree._ParserContext._handleParseResultDoc (src/lxml/lxml.etree.c:91290)
File "parser.pxi", line 683, in lxml.etree._handleParseResult (src/lxml/lxml.etree.c:92476)
File "parser.pxi", line 633, in lxml.etree._raiseParseError (src/lxml/lxml.etree.c:91939)
lxml.etree.XMLSyntaxError: None
المحلول
وكما ذكر جوناثان، قد يكون هذا نتيجة scraperwiki.pdftoxml()
وهذا يسبب مشكلة.يمكنك عرض أو تسجيل قيمة x
لتأكيد ذلك.
خاصة، pdftoxml()
يدير برنامج خارجي pdftohtml
ويستخدم ملفات مؤقتة لتخزين ملفات PDF وXML.
ما سأتحقق منه أيضًا هو:
- يكون
pdftohtml
إعداد بشكل صحيح على الخادم الخاص بك? - إذا كان الأمر كذلك، فهل يعمل التحويل إلى XML إذا قمت بتشغيله مباشرة في shell على الخادم باستخدام ملف PDF الذي فشل الكود فيه؟الأمر الذي ينفذه هو
pdftohtml -xml -nodrm -zoom 1.5 -enc UTF-8 -noframes "input.pdf" "output.xml"
إذا كانت هناك مشكلة عند تشغيل الأمر مباشرة، فهذه تكمن مشكلتك.مع الطريق pdftohtml
يعمل في scraperwiki
التعليمات البرمجية، ليست هناك طريقة سهلة يمكنك من خلالها معرفة ما إذا فشل الأمر.
نصائح أخرى
في طريقهم، أود أن أذهب حول هذا هو إضافة جرب: باستثناء: جملة وعندما تحصل على الخطأ الذي تحفظه ببساطة حفظ ملف XML وكذلك الرابط لأسفل إلى Harddrive الخاص بك.بهذه الطريقة يمكنك فحص ملف XML بشكل منفصل.
قد يكون هذا scraperwiki.pdftoxml يجعل ملف XML غير قانوني لسبب ما.كان لدي ذلك يحدث لي عند استخدام أداة PDFToxml أخرى.
، يرجى إعادة تكوين التعليمات البرمجية الخاصة بك في المزيد من الوظائف، سيصبح أسهل كثيرا في القراءة والصيانة :).
طريقة أخرى تنزيل بالطبع لتنزيل جميع ملفات PDF أولا، ثم تحليلها جميعا.وبهذه الطريقة يمكنك تجنب ضرب موقع الويب عدة مرات كلما فشلت لسبب ما.