Skip to main content

A Python web scraping library using HTML

Project description

HTMS: HTML-based Web Scraping Library

Overview

HTMSLParser is a Python library for web scraping using an HTML-like configuration. It simplifies data extraction, handles pagination, and supports custom parsing, making it easy to gather structured data from websites with minimal coding.

Features

  • Declarative Scraping Configuration: Define scraping tasks using an HTML-like syntax to specify requests, lists, items, and outputs.
  • Supports XPath Data Extraction
  • Pagination Handling: Automatically manage pagination by defining start, end, and URL templates.
  • Follow-up Requests: Enable follow-up scraping on specific items based on extracted data from initial requests.
  • Multiple Parsers: Combine and use multiple parsers for complex scraping tasks.
  • Flexible Data Extraction: Use XPath for precise data extraction, including support for custom parsing and filtering.
  • JSON Output: Export scraped data directly to JSON files.
  • Item Data Manipulation: Strip whitespace, parse data, and apply filters to extracted items.
  • Request Configuration: Supports GET and POST methods with customizable headers.

Installation

You can install the package using pip if it is available on PyPI:

pip install htms

Alternatively, to install htms, simply clone the repository and include it in your project:

git clone https://github.com/BowangLan/htms.git

Getting Started

htms lets you specify common web scraping tasks in HTML. To run an htms HTML file therefore is to run web scraping tasks described inside the HTML file.

Command for running an htms HTML file:

python -m htms <your-html-file>

Alternatively, you can use call the Python API to run the HTML file:

from htms import HTMSParser

with open('your-html-file.html', 'r') as file:
    html_str = file.read()

parser = HTMSParser()
parser.feed(html_str)
parser.start()

Run Examples

A list of example HTML files are included in this repo under src/htms/example_html folder. To run these, use this command:

python -m htms.examples <example-file-name>

You can see a full list of example files using this command:

python -m htms.examples

HTML Configuration

Basic Example

Suppose you want to scrape badminton club locations from badmintonclubs.org. The following configuration will extract the name and href of each club listed on the site:

<request url="https://badmintonclubs.org">
  <list xpath="//map/area" name="locations" key="href">
    <item
      name="name"
      xpath="@title"
      parse="value.split('badminton in ')[1] if value else None"
    ></item>
    <item name="href" xpath="@href"></item>
  </list>
</request>

You make a request by a RequestTag . Then, you create a ListTag inside this request tag for parsing the output of this request. Then, for each location element extract by xpath in the ListTag , you extract two fields (name and value) by nesting two ItemTag inside the ListTag .

  • key attribute in the list tag tells the parser to remove duplicates of the extracted object list by the provided key. In the above case, locations that has the same href are dropped.

This HTML snippet is equivalent to the followinig Python code:

import requests
from lxml import html

output = []

url = "https://badmintonclubs.org"
response = requests.get(url)

tree = html.fromstring(response.content)

locations = tree.xpath("//map/area")

result = []
for location in locations:
    name = location.xpath("@title")[0] if location.xpath("@title") else None
    href = location.xpath("@href")[0] if location.xpath("@href") else None
    
    # Parse the name field according to the provided logic
    if name:
        name = name.split('badminton in ')[1] if 'badminton in ' in name else None
    
    result.append({
        "name": name,
        "href": href
    })

href_set = set()
new_result = []
for item in result:
    if item['href'] in href_set:
        continue
    href_set.add(item['href'])
    new_result.append(iem)
result = new_result

output.append({
  "locations": result
})

ListTag and ItemTag

ItemTag and ListTag are abstractions designed to simplify the process of extracting and processing data from HTML responses in a structured and intuitive manner. These abstractions allow you to define the extraction logic using a declarative syntax, making it easy to manage complex scraping tasks.

ItemTag

The ItemTag represents a single data extraction operation. It is used to extract a single value from a given HTML element based on the specified XPath.

Attributes for both ItemTag and ListTag :

  • name: The name of the field being extracted.
  • id (optional): An optional global id of the parser.
  • xpath: The XPath expression used to locate the data within the HTML element.
  • parse (optional): An optional inline Python expression runs after all other processing steps and right before returning the extracted value.
  • pre-parse (optional): An optional inline Python expression that runs before passing the value to child parsers.

Attributes specific to ItemTag :

  • strip: Strip whitespace and \n from string values.

Example Usage:

<item name="title" xpath="//h1/text()" parse="value.strip()"></item>

This example extracts the text content of an <h1> element, and then applies a strip() operation to remove any leading or trailing whitespace.

ListTag

The ListTag is an extension of ItemTag that handles the extraction of multiple values from a list of HTML elements. It is useful when you need to process a collection of similar elements, such as a list of articles or links.

Attributes specific to ListTag :

  • All attributes of ItemTag.
  • key (optional): The field by which to remove duplicates from the list.
  • filter (optional)

Example Usage:

<list xpath="//div[@class='articles']/article" name="articles" key="url">
  <item name="title" xpath=".//h2/text()" />
  <item name="url" xpath=".//a/@href" />
</list>

This example extracts a list of articles from a page. Each article has a title and a url, and duplicates are removed based on the url field.

RequestTag

The RequestTag represents a single HTTP request and the associated data extraction process.

The response of the request is parsed based on the type attribute, which specifies the type of response.

The child tags of a RequestTag can be:

  • ItemTag or ListTag for data extraction.
  • ExportTag for exporting data.
  • ... (TODO)

Attributes:

  • url: URL of the request.
  • parsers (optional): An optional string field for specifying external parsers ( ListTag or ItemTag ) by id separated by , .
  • type (optional): Specifies the type of response. Either "json" or "html". Default to "html" .
  • method (optional)

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

htms-0.1.10.tar.gz (18.2 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

htms-0.1.10-py3-none-any.whl (22.0 kB view details)

Uploaded Python 3

File details

Details for the file htms-0.1.10.tar.gz.

File metadata

  • Download URL: htms-0.1.10.tar.gz
  • Upload date:
  • Size: 18.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/1.6.1 CPython/3.11.0 Darwin/22.5.0

File hashes

Hashes for htms-0.1.10.tar.gz
Algorithm Hash digest
SHA256 2659c21c977574090feac37b902ba55dbf368b9d995405c7bfd9ccbab527ca31
MD5 4a51780b5fc06f40c6ab1591a1809faa
BLAKE2b-256 17c7e1f8f4870c7087c5d1672837cc5dc6a53ec1b46fc4c032fa29ca28122dd0

See more details on using hashes here.

File details

Details for the file htms-0.1.10-py3-none-any.whl.

File metadata

  • Download URL: htms-0.1.10-py3-none-any.whl
  • Upload date:
  • Size: 22.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/1.6.1 CPython/3.11.0 Darwin/22.5.0

File hashes

Hashes for htms-0.1.10-py3-none-any.whl
Algorithm Hash digest
SHA256 7e096431cc7ad6006b4caf1ee3244fce851052a3ab4faead418b6556cc1d343d
MD5 01914ea81538b92b06180b169a3b2cda
BLAKE2b-256 b19ede92c6302471a61fd5d2f635917813ac20e9f5b88c8fa204539ef8196162

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page