QuiddityML

By · 28 October 2026 · 5 min read

Privacy and licensing: can you train a model on scraped text?

What to check before you collect or publish a text dataset, what a dataset license spells out, and a short Python example that masks emails, phone numbers and IP addresses.

Text collected for a model often contains personal details about real people, and it usually belongs to someone. Privacy and licensing are the two checks that decide whether you may use that text at all. Skipping them can hurt the people named in the data and can leave you legally liable for what you trained or published.

Can you train on text you can read online?

Text you can read online is not automatically yours to train on. Scraped text is usually owned by someone, most often whoever wrote or published it. Copyright is that ownership, and it covers the text whether or not the page sits behind a login.

Being able to read a page in a browser does not mean you are free to redistribute it or train on it. Reading is one use the owner allowed. Copying the text into a corpus, sharing that corpus or training a model on it are separate uses, and the owner may not have allowed any of them.

What a dataset license tells you

A license is the written terms that come with a dataset. It spells out what you may do with the data. The three questions it usually answers are:

A dataset with no license is not free to use. It means nobody has granted you any rights, so the safe reading is that you have none.

Personal information hiding in raw text

Personally identifiable information (PII) is any detail that points to a specific person. Common examples are names, email addresses and phone numbers. Home addresses, order numbers and IP addresses count too. Support tickets, forum posts, emails and scraped web pages all contain it, and it often sits in the middle of ordinary sentences.

PII usually has to be found and then removed or masked. Masking means replacing each detail with a placeholder such as [EMAIL], so the sentence keeps its shape and the person disappears from it. This protects the people in the data, and it is also how many teams meet the privacy regulations that apply to them.

Masking PII in Python

Some PII has a fixed shape. An email address always has an @ in the middle and an IP address is four numbers joined by dots. A regular expression (a pattern that matches text of a given shape) can find each kind and swap it for a tag:

1import re
2 
3record = """Name: Alex Johnson
4Email: [email protected]
5Phone: +1 (555) 123-4567
6IP: 203.0.113.42
7Note: Alex asked to cancel order ORD-987654."""
8 
9patterns = {
10    "[EMAIL]": r"[\w.+-]+@[\w-]+\.[\w.-]+",
11    "[PHONE]": r"\+?\d[\d\s()-]{7,}\d",
12    "[IP_ADDRESS]": r"\b\d{1,3}(?:\.\d{1,3}){3}\b",
13    "[ORDER_ID]": r"\bORD-\d+\b",
14}
15 
16masked = record
17for tag, pattern in patterns.items():
18    masked = re.sub(pattern, tag, masked)
19print(masked)
20print()
21 
22# Names have no fixed shape, so a pattern cannot find them.
23# Here they come from a list of known names instead.
24known_names = ["Alex Johnson", "Alex"]
25for name in known_names:
26    masked = re.sub(r"\b" + re.escape(name) + r"\b", "[NAME]", masked)
27print(masked)

The first print shows the patterns at work:

1Name: Alex Johnson
2Email: [EMAIL]
3Phone: [PHONE]
4IP: [IP_ADDRESS]
5Note: Alex asked to cancel order [ORDER_ID].

The email, phone number, IP address and order number are gone. The name is still there twice. A name has no fixed shape, so no pattern above can tell Alex from any other capitalized word. The second step masks names from a list, and the second print has nothing personal left:

1Name: [NAME]
2Email: [EMAIL]
3Phone: [PHONE]
4IP: [IP_ADDRESS]
5Note: [NAME] asked to cancel order [ORDER_ID].

A list only covers the names you knew to put on it. On real data, check a sample of the masked output by hand before trusting it, because the details that slip through are usually the ones without a fixed shape.

A checklist before collection or release

Privacy and licensing come before the modeling work. Check them before you collect a corpus and again before you release one. The checks fall into four groups:

  1. PII masking: personal details are removed or replaced with placeholders.
  2. License check: the dataset's license allows your use. If you start from a pretrained model, its own license has terms too. Text copied in from other sources (third-party content) and the libraries and tools your pipeline pulls in (dependencies) each come with their own terms.
  3. Consent and source: the people in the data agreed to this kind of use, and the use matches the purpose they agreed to. Text written by or about children gets extra protection. Anyone who asked to be left out (an opt-out) has been removed. The source of every part of the corpus is written down, which is also called its provenance.
  4. Cleared for release: every check above passed, so the data is safe to train on or publish.

If any check fails, stop and fix it before moving on.

Raw text with a name, email, phone, address, order ID and IP address passing through PII masking, a license check, a consent and source check and a final clearance step, with a stop sign for any failed check

Common mistakes

Privacy and licensing sit next to the other checks on a text dataset. The post on data quality problems in NLP covers duplicates, contamination, bias and representativeness. The post on building your own NLP dataset covers documenting a dataset, which is where the license and the source of each part get written down for the next person.

QuiddityML teaches privacy and licensing as its own concept in the NLP track's data unit, and its exercises ask what to check before training on text from a public website (QuiddityML).