dragnet

Just the facts -- web page content extraction

https://github.com/dragnet-org/dragnet

Science Score: 23.0%

This score indicates how likely this project is to be science-related based on various indicators:

  • CITATION.cff file
  • codemeta.json file
    Found codemeta.json file
  • .zenodo.json file
  • DOI references
  • Academic publication links
  • Committers with academic emails
    1 of 21 committers (4.8%) from academic institutions
  • Institutional organization owner
  • JOSS paper metadata
  • Scientific vocabulary similarity
    Low similarity (13.1%) to scientific vocabulary
Last synced: 11 months ago · JSON representation

Repository

Just the facts -- web page content extraction

Basic Info
  • Host: GitHub
  • Owner: dragnet-org
  • License: mit
  • Language: Python
  • Default Branch: master
  • Size: 332 MB
Statistics
  • Stars: 1,271
  • Watchers: 129
  • Forks: 181
  • Open Issues: 23
  • Releases: 3
Created about 14 years ago · Last pushed about 1 year ago
Metadata Files
Readme Changelog License

README.md

Dragnet

Build Status

Dragnet isn't interested in the shiny chrome or boilerplate dressing of a web page. It's interested in... 'just the facts.' The machine learning models in Dragnet extract the main article content and optionally user generated comments from a web page. They provide state of the art performance on a variety of test benchmarks.

For more information on our approach check out:

This project was originally inspired by Kohlschütter et al, Boilerplate Detection using Shallow Text Features and Weninger et al CETR -- Content Extraction with Tag Ratios, and more recently by Readability.

GETTING STARTED

Depending on your use case, we provide two separate functions to extract just the main article content or the content and any user generated comments. Each function takes an HTML string and returns the content string.

```python import requests from dragnet import extractcontent, extractcontentandcomments

fetch HTML

url = 'https://moz.com/devblog/dragnet-content-extraction-from-diverse-feature-sets/' r = requests.get(url)

get main article without comments

content = extract_content(r.content)

get article and comments

contentcomments = extractcontentandcomments(r.content) ```

We also provide a sklearn-style extractor class(complete with fit and predict methods). You can either train an extractor yourself, or load a pre-trained one: ```python from dragnet.util import loadpickledmodel

contentextractor = loadpickledmodel( 'kohlschuetterreadabilityweningercontentmodel.pkl.gz') contentcommentsextractor = loadpickledmodel( 'kohlschuetterreadabilityweningercommentscontentmodel.pkl.gz')

content = contentextractor.extract(r.content) contentcomments = contentcommentsextractor.extract(r.content) ```

A note about encoding

If you know the encoding of the document (e.g. from HTTP headers), you can pass it down to the parser:

python content = content_extractor.extract(html_string, encoding='utf-8')

Otherwise, we try to guess the encoding from a meta tag or specified <?xml encoding=".."?> tag. If that fails, we assume "UTF-8".

Installing

Dragnet is written in Python (developed with 2.7, with support recently added for 3) and built on the numpy/scipy/Cython numerical computing environment. In addition we use lxml (libxml2) for HTML parsing.

We recommend installing from the master branch to ensure you have the latest version.

Installing with Docker:

This is the easiest method to install Dragnet and builds a Docker container with Dragnet and its dependencies.

  1. Install Docker.
  2. Clone the master branch: git clone https://github.com/dragnet-org/dragnet.git
  3. Build the docker container: docker build -t dragnet .
  4. Run the tests: docker run dragnet make test

You can also run an interactive Python session: bash docker run -ti dragnet python3

Installing without Docker

  1. Install the dependencies needed for Dragnet. The build depends on GCC, numpy, Cython and lxml (which in turn depends on libxml2). We use provision.sh to setup the dependencies in the Docker container, so you can use it as a template and modify as appropriate for your operation system.
  2. Clone the master branch: git clone https://github.com/dragnet-org/dragnet.git
  3. Install the requirements: cd dragnet; pip install -r requirements.txt
  4. Build dragnet:

```bash $ cd dragnet $ make install

these should now pass

$ make test ```

Contributing

We love contributions! Open an issue, or fork/create a pull request.

More details about the code structure

The Extractor class encapsulates a blockifier, some feature extractors and a machine learning model.

A blockifier implements blockify that takes a HTML string and returns a list of block objects. A feature extractor is a callable that takes a list of blocks and returns a numpy array of features (len(blocks), nfeatures). There is some additional optional functionality to "train" the feature (e.g. estimate parameters needed for centering) specified in features.py. The machine learning model implements the scikits-learn interface (predict and fit) and is used to compute the content/no-content prediction for each block.

Training/test data

The training and test data is available at dragnet_data.

Training content extraction models

  1. Download the training data (see above). In what follows ROOTDIR contains the root of the dragnet_data repo, another directory with similar structure (HTML and Corrected sub-directories).
  2. Create the block corrected files needed to do supervised learning on the block level. First make a sub-directory $ROOTDIR/block_corrected/ for the output files, then run:

    python from dragnet.data_processing import extract_all_gold_standard_data rootdir = '/path/to/dragnet_data/' extract_all_gold_standard_data(rootdir)

    This solves the longest common sub-sequence problem to determine which blocks were extracted in the gold standard. Occasionally this will fail if lxml (libxml2) cannot parse a HTML document. In this case, remove the offending document and restart the process.

  3. Use k-fold cross validation in the training set to do model selection and set any hyperparameters. Make decisions about the following:

* Whether to use just article content or content and comments.
* The features to use
* The machine learning model to use

For example, to train the randomized decision tree classifier from
sklearn using the shallow text features from Kohlschuetter et al.
and the CETR features from Weninger et al.:

```python
from dragnet.extractor import Extractor
from dragnet.model_training import train_model
from sklearn.ensemble import ExtraTreesClassifier

rootdir = '/path/to/dragnet_data/'

features = ['kohlschuetter', 'weninger', 'readability']

to_extract = ['content', 'comments']   # or ['content']

model = ExtraTreesClassifier(
    n_estimators=10,
    max_features=None,
    min_samples_leaf=75
)
base_extractor = Extractor(
    features=features,
    to_extract=to_extract,
    model=model
)

extractor = train_model(base_extractor, rootdir)
```

This trains the model and, if a value is passed to `output_dir`, writes a
pickled version of it along with some some *block level* classification
errors to a file in the specified `output_dir`. If no `output_dir` is
specified, the block-level performance is printed to stdout.
  1. Once you have decided on a final model, train it on the entire training data using dragnet.model_training.train_models.
  2. As a last step, test the performance of the model on the test set (see below).

Evaluating content extraction models

Use evaluate_models_predictions in model_training to compute the token level accuracy, precision, recall, and F1. For example, to evaluate a trained model run:

```python from dragnet.compat import traintestsplit from dragnet.dataprocessing import preparealldata from dragnet.modeltraining import evaluatemodelpredictions

rootdir = '/path/to/dragnetdata/' data = preparealldata(rootdir) trainingdata, testdata = traintestsplit(data, testsize=0.2, random_state=42)

testhtml, testlabels, testweights = extractor.gethtmllabelsweights(testdata) trainhtml, trainlabels, trainweights = extractor.gethtmllabelsweights(trainingdata)

extractor.fit(trainhtml, trainlabels, weights=trainweights) predictions = extractor.predict(testhtml) scores = evaluatemodelpredictions(testlabels, predictions, testweights) ```

Note that this is the same evaluation that is run/printed in train_model

Owner

  • Name: dragnet-org
  • Login: dragnet-org
  • Kind: organization

GitHub Events

Total
  • Watch event: 32
  • Issue comment event: 1
  • Fork event: 3
Last Year
  • Watch event: 32
  • Issue comment event: 1
  • Fork event: 3

Committers

Last synced: about 1 year ago

All Time
  • Total Commits: 290
  • Total Committers: 21
  • Avg Commits per committer: 13.81
  • Development Distribution Score (DDS): 0.683
Past Year
  • Commits: 0
  • Committers: 0
  • Avg Commits per committer: 0.0
  • Development Distribution Score (DDS): 0.0
Top Committers
Name Email Commits
Matthew Peters m****t@s****g 92
Matthew Peters m****t@m****m 74
Patrick Kelley p****y@b****m 37
Burton DeWilde b****n@c****m 31
Burton DeWilde b****e@g****m 17
Brandon Forehand b****n@m****m 10
Dan Lecocq d****n@s****g 6
Matthew Peters m****p@a****g 6
TanakaHiroyuki h****i@T****l 4
Duc Bui d****i@u****u 2
amrrs a****s@o****m 1
Pierce Freeman p****n 1
Nicholaus Halecky n****y@g****m 1
Maura Hubbell m****a@m****m 1
Jerry Nieuviarts j****y@m****m 1
Jeffrey Scott Keone Payne j****e@g****m 1
Evan Cofsky m****t 1
Artur Geraschenko a****b@g****m 1
fabio fumarola f****a@g****m 1
zerocity p****n@g****m 1
zubieta c****a@w****m 1
Committer Domains (Top 20 + Academic)

Issues and Pull Requests

Last synced: 11 months ago

All Time
  • Total issues: 51
  • Total pull requests: 52
  • Average time to close issues: 3 months
  • Average time to close pull requests: about 1 month
  • Total issue authors: 38
  • Total pull request authors: 19
  • Average comments per issue: 4.22
  • Average comments per pull request: 2.81
  • Merged pull requests: 43
  • Bot issues: 0
  • Bot pull requests: 0
Past Year
  • Issues: 1
  • Pull requests: 0
  • Average time to close issues: N/A
  • Average time to close pull requests: N/A
  • Issue authors: 1
  • Pull request authors: 0
  • Average comments per issue: 0.0
  • Average comments per pull request: 0
  • Merged pull requests: 0
  • Bot issues: 0
  • Bot pull requests: 0
Top Authors
Issue Authors
  • bdewilde (7)
  • gvola (4)
  • mtlive (2)
  • fedecaccia (2)
  • slitayem (2)
  • pakelley (2)
  • yeus (1)
  • zcs-seu (1)
  • mbowiewilson (1)
  • rw (1)
  • siavash9000 (1)
  • Nitin-Panwar (1)
  • ggada (1)
  • 127 (1)
  • AppleSeedExp (1)
Pull Request Authors
  • matt-peters (16)
  • pakelley (9)
  • bdewilde (7)
  • b4hand (5)
  • theunixman (1)
  • 127 (1)
  • vergili (1)
  • zerocity (1)
  • zubieta (1)
  • fabiofumarola (1)
  • brettscott (1)
  • ducalpha (1)
  • r22gdl (1)
  • Yomguithereal (1)
  • nkt1546789 (1)
Top Labels
Issue Labels
wontfix (1)
Pull Request Labels

Dependencies

requirements.txt pypi
  • Cython >=0.21.1
  • ftfy >=4.1.0,<5.0.0
  • lxml >=4.2.3
  • numpy >=1.11.0
  • pytest >=4.0.0
  • pytest-cov >=2.6.0
  • scikit-learn >=0.15.2,<0.21.0
  • scipy >=0.17.0
setup.py pypi
  • Cython >=0.21.1
  • ftfy >=4.1.0,<5.0.0
  • lxml *
  • numpy >=1.11.0
  • scikit-learn >=0.15.2,<0.21.0
  • scipy >=0.17.0
Dockerfile docker
  • ubuntu 20.04 build