read_html() parses the HTML looking specifically for table tags and attempts to convert each one into a DataFrame, returning a list since a page can contain multiple tables — even if you expect only one, the result is still a list, and you typically index into it to get the table you want. The match parameter, a string or regex, filters down to only tables containing matching text, which is useful for pages with several unrelated tables, and attrs lets you target a table by its HTML attributes, like a specific id or class.
1Understanding pd.read_html()
read_html() parses the HTML looking specifically for table tags and attempts to convert each one into a DataFrame, returning a list since a page can contain multiple tables — even if you expect only one, the result is still a list, and you typically index into it to get the table you want. The match parameter, a string or regex, filters down to only tables containing matching text, which is useful for pages with several unrelated tables, and attrs lets you target a table by its HTML attributes, like a specific id or class.
read_html() always returns a list of DataFrames, even for a page with exactly one table — a common mistake is treating the result as a single DataFrame directly instead of indexing into the list first.
import pandas as pd
tables = pd.read_html("https://example.com/stats")
print(len(tables))
print(tables[0].head(2))2Practical Example
Here is a real-world application of pd.read_html() showing how it is used in production Pandas code.
import pandas as pd
tables = pd.read_html("https://example.com/stats", match="Score")
df = tables[0]
print(df.shape)3Best Practices
Follow these guidelines when working with pd.read_html():
1. Remember read_html() always returns a list — index into it, typically at position 0, to get a specific table as an actual DataFrame
2. Use the match parameter to narrow down to the relevant table on pages with multiple unrelated tables, instead of guessing at a list index
3. Expect to do follow-up cleanup, dtype conversion, dropping unwanted header/footer rows, after read_html(), since HTML tables are rarely as cleanly structured as a proper CSV export
Tip: read_html() always returns a list of DataFrames, even for a page with exactly one table — a common mistake is treating the result as a single DataFrame directly instead of indexing into the list first.
import pandas as pd
tables = pd.read_html("https://example.com/stats")
print(len(tables))
print(tables[0].head(2))