As Stefano suggested you need to specify the relevant pages and set the option flavor='stream'
. The default flavor='lattice'
only works if there are lines between the cells.
Additionally, increasing row_tol
helps to group rows together. So that, for example, the header of the first table is not read as three separate rows but as one row. Specifically 'Concentração/Composição' is identified as coherent text.
Also you may want to use strip_text='\n'
to remove new line characters.
This results in (reading page 17 and 18 as an example):
import camelot
file = 'relacao_medicamentos_rename_2020.pdf'
tables = camelot.read_pdf(file, pages='17, 18', flavor='stream', row_tol=20, strip_text='\n')
tables.export('foo.csv', f='csv', compress=False)
Still, this way you end up with one table per page and one csv file per table. I.e. in the example above you get two .csv files. This needs to be handled outside camelot.
To merge tables spanning multiple pages using pandas:
import pandas as pd
dfs = [] # list to store dataframes
for table in tables:
df = table.df
df.columns = df.iloc[0] # use first row as header
df = df[1:] # remove the first row from the dataframe
dfs.append(df)
df = pd.concat(dfs, axis=0) # concatenate all dataframes in list
df.to_csv('foo.csv') # export dataframe to csv
Also, there are difficulties identifying table areas on pages containing both text and tables (e.g. pdf page 16).
In these cases the table area can be specified. For the table on page 16, this would be:
tables = camelot.read_pdf(in_dir + file, pages='16', flavor='stream', row_tol=20, strip_text='\n', table_areas=['35,420,380,65'],)
Note: Throughout the post I referenced pages by 'counting' the pages of the file and not by the page numbers printed on each page (the latter one starts at the second page of the document).