用Python将PDF转换为文本/HTML以便解析
我有一段示例代码,用来从欧洲议会网站下载一个关于某个立法提案的PDF文件:
补充说明:最后我只是获取了链接,然后把它放到Adobe的在线转换工具里(见下面的代码):
import mechanize
import urllib2
import re
from BeautifulSoup import *
adobe = "http://www.adobe.com/products/acrobat/access_onlinetools.html"
url = "http://www.europarl.europa.eu/oeil/search_reference_procedure.jsp"
def get_pdf(soup2):
link = soup2.findAll("a", "com_acronym")
new_link = []
amendments = []
for i in link:
if "REPORT" in i["href"]:
new_link.append(i["href"])
if new_link == None:
print "No A number"
else:
for i in new_link:
page = br.open(str(i)).read()
bs = BeautifulSoup(page)
text = bs.findAll("a")
for i in text:
if re.search("PDF", str(i)) != None:
pdf_link = "http://www.europarl.europa.eu/" + i["href"]
pdf = urllib2.urlopen(pdf_link)
name_pdf = "%s_%s.pdf" % (y,p)
localfile = open(name_pdf, "w")
localfile.write(pdf.read())
localfile.close()
br.open(adobe)
br.select_form(name = "convertFrm")
br.form["srcPdfUrl"] = str(pdf_link)
br["convertTo"] = ["html"]
br["visuallyImpaired"] = ["notcompatible"]
br.form["platform"] =["Macintosh"]
pdf_html = br.submit()
soup = BeautifulSoup(pdf_html)
page = range(1,2) #can be set to 400 to get every document for a given year
year = range(1999,2000) #can be set to 2011 to get documents from all years
for y in year:
for p in page:
br = mechanize.Browser()
br.open(url)
br.select_form(name = "byReferenceForm")
br.form["year"] = str(y)
br.form["sequence"] = str(p)
response = br.submit()
soup1 = BeautifulSoup(response)
test = soup1.find(text="No search result")
if test != None:
print "%s %s No page skipping..." % (y,p)
else:
print "%s %s Writing dossier..." % (y,p)
for i in br.links(url_regex="file.jsp"):
link = i
response2 = br.follow_link(link).read()
soup2 = BeautifulSoup(response2)
get_pdf(soup2)
在get_pdf()这个函数里,我想把PDF文件转换成文本,这样我就可以从文本中提取关于立法程序的信息。有没有人能告诉我该怎么做?
托马斯
2 个回答
14
听起来你已经找到了解决办法,但如果你想在没有网络服务的情况下处理,或者需要根据PDF页面上数据的具体位置来抓取数据,我可以推荐我的一个库,pdfquery。这个库的主要功能是把PDF文件转换成一个lxml树结构,然后你可以把它输出为XML,或者用XPath、PyQuery等其他工具来解析。
使用这个库时,只要把文件保存到电脑上,你可以用 pdf = pdfquery.PDFQuery(name_pdf)
来加载它,或者如果你不需要保存文件,可以直接传入一个urllib文件对象。想要把数据输出为XML以便用BeautifulSoup解析,你可以使用 pdf.tree.tostring()
。
如果你不介意使用类似JQuery的选择器,还有一个带有位置扩展的PyQuery接口,这样会很方便。例如:
balance = pdf.pq(':contains("Your balance is")').text()
strings_near_the_bottom_of_page_23 = [el.text for el in pdf.pq('LTPage[page_label=23] :in_bbox(0, 0, 600, 200)')]
2
这其实并不是魔法。我建议你:
- 先把PDF文件下载到一个临时文件夹,
- 然后用一个外部程序把里面的文字提取出来,存到一个(临时的)文本文件里,
- 最后读取这个文本文件。
关于提取文本的命令行工具,你可以参考很多选择,还有一些可能在链接里没有提到的(比如基于Java的)。先试试这些工具,看看哪个适合你的需求。也就是说,先分别尝试每一步(找到链接、下载文件、提取文本),然后再把它们组合起来。调用外部程序时,可以使用subprocess.Popen
或subprocess.call()
。