

# How to Turn Job Descriptions Into a Skills Learning Plan

Use a small set of full job descriptions to find repeated duties. Then prove those duties with one project.

This plan is for a person who must choose what to study. You get a skills matrix and a ranked learning plan. A skills matrix is a table of skills, duties, classes, and proof.

An Actor is a hosted data collection program. A Task is a saved input preset. The [LinkedIn Jobs Actor](https://apify.com/chronometrica/linkedin-jobs-scraper) collects job rows. You read those rows and write the plan. The Actor does not label skills. It does not measure your ability. It does not write the plan.

A field is one named input or one named output. A row is one collected job record. Build 0.2.19 was checked on 13 October 2026. It accepts `searchTerm`, `location`, `maxItems`, `maxPagesPerSearch`, `postedWithin`, `saveOnlyUniqueItems`, and `fetchJobDetails`.

The public [skills demand Task](https://apify.com/chronometrica/linkedin-jobs-scraper/examples/linkedin-skills-demand) is only a starting input. It does not mean the analysis happens for you.

A [recent graduate asked which skills to learn](https://www.reddit.com/r/FresherTechJobsIndia/comments/1ncge8k/recent_data_science_graduate_seeking_advice/). That question shows the need for a study choice. It does not prove that this plan gets interviews. It does not measure the size of any job market.

## 1. State the learning decision

Write four choices before you collect listings. A listing is one job ad.

Name one role family. A role family is one kind of job, such as data analyst. Name one level. Entry level means a first job in that role. Name one market. A market is the country or city where you want to work. Write the date you read the listings.

This is a study plan for that choice. It is not proof of a national skill shortage. It is not a promise of interviews.

Do not mix senior jobs with first-job analyst jobs. If you need both groups, study each group apart. Do not mix two markets in one table.

The lesson later in this article is original fiction. It uses entry-level data analyst work. It uses one made-up market called Market One. Its read date is 13 October 2026. The same calendar date is also the Actor check date. That match does not mean these jobs were collected.

## 2. Collect full descriptions

Check each row before you label a skill. Confirm the job identity. Confirm that the full text is present. Confirm whether the row cap or a failed run stopped the collection.

A row cap is the most rows you ask to collect. A failed run is unknown. Do not treat a failed run as zero jobs.

Use the saved Task input only as a start:

```json
{"searchTerm": "data engineer\nsoftware engineer\nproduct manager", "startUrls": [], "saveOnlyUniqueItems": true}
```

2. Collect full descriptions

That input mixes data engineer, software engineer, and product manager. Replace the mix with one role and one market. The empty `startUrls` list is part of the saved input. This method uses the seven fields named above.

For a first small check, enter these values:

| Field | Value |
| --- | --- |
| searchTerm | data analyst |
| location | your one market |
| postedWithin | any |
| maxItems | 3 |
| maxPagesPerSearch | 1 |
| saveOnlyUniqueItems | true |
| fetchJobDetails | true |

This check is a text sample. It is not every open job. It is not a full survey of employers.

Keep these output fields on every row you review:

| Field | What it holds |
| --- | --- |
| jobId | The source job identity |
| title | The job title |
| companyName | The employer name |
| locationRaw | The location text on the job |
| descriptionText | The job description |
| descriptionStatus | Whether the full text is available |
| jobUrl | The link to the source job |
| query | The search words for that row |
| searchLocation | The market you searched |
| scrapedAt | The time the row was collected |

`descriptionStatus` has two useful values. `full` means the description is complete enough to label. `missing` means the full text is unavailable. If the status is missing, do not label skills. Count the row as a gap.

A title alone can omit duties. A short excerpt can hide a required duty. It can also make a preferred skill look required. Read `descriptionText`.

Some optional fields can be absent. Absent is not the same as zero. If `companyName` is absent, the employer is unknown. Do not invent a name. If `jobUrl` is absent, keep the row only if `jobId` still identifies it.

Use `jobId` to drop repeated copies of the same listing. Keep one copy. Do not drop two different listings only because one employer posted both. Keep the employer on each listing. One employer with many listings can make a skill look more common than it is.

Check `query` and `searchLocation`. If they do not match your role and market, leave the row out of this group. If `locationRaw` names a different market, leave that listing out. Do not mix it into Market One or into your real market.

A control check of build 0.2.19 collected three source job IDs. It also collected source URLs, collection times, and full `descriptionText`. That control used a different role and a different market. It hit the three-row cap. Those three rows are not all jobs in that market. The control shows that full text can be collected. It does not choose skills for data analyst work. It does not support the fictional counts below.

## 3. Save one evidence row per skill

Read one full description at a time. For each skill or duty, save one evidence row.

Save the job, the employer, and the exact source sentence. Save the source link when you have a real `jobUrl`. Save a short skill name, a requirement class, the duty, and a note.

A requirement class is the label you give after you read the sentence. Use only four labels.

- Required means the text says you must have the skill.
- Preferred means the text asks for the skill but does not say it is required.
- Context means the text names a tool, but not as a test for you.
- Unclear means you cannot tell the class from the words.

The sentence "We use Python" is not enough. Do not label Python as required from that sentence alone. Label it context or unclear.

Keep the original words. Do not replace them with a smoother sentence before you label the class.

A [raw word count](/en/articles/jobs-skill-term-coding/) treats every mention as equal. The class stops that mistake. A preferred skill is not a required skill. A context mention is not a skill you must learn first.

## 4. Keep a small skill list

Choose one short skill name for each skill. Keep the original words beside that name.

SQL is a language used to ask questions of tables. Use one skill name for SQL and Structured Query Language only when the text means that same language.

Do not merge Java and JavaScript. They are different languages. Do not merge chart work with one product name. Do not merge every cloud service into one skill. A cloud service is software reached over the internet. Different services can be different skills.

A synonym is a different word for the same skill. You decide synonyms by hand. If two labels conflict, keep both notes. Do not claim that an automatic skill tool did this work. This Actor does not label skills.

## 5. Count listings and employers apart

Listing count means how many different listings state the skill in that class. Employer count means how many different employers state it. Three listings from one employer are three listing mentions. They are still one employer.

Report the class with both counts. Use only listings with full text as the listing total. Do not call the result customer demand. Do not call it a national rate. Do not call it hiring growth. This kind of search is not a random sample of all jobs.

### Fictional sample

The tables below are original fiction. They teach the counts. They are not Actor output. They are not the three-row control.

The fiction has six listings you can label. Five employers posted them. Employer A posted J1 and J2. Employer B posted J3. Employer C posted J4. Employer D posted J5. Employer E posted J6. The labels J1 to J7 are lesson names. They are not source IDs. This fiction has no source URL. In a real table, save `jobId` and `jobUrl`.

A seventh collected row, J7, has no `descriptionText`. Its fictional status is missing. Its skills are unknown. Unknown is not zero. Leave J7 out of the skill counts. State the gap. One of seven collected rows cannot be labeled. The listing total for skills is six, not seven.

| Job | Employer | Full text | SQL | Spreadsheets | Python | Dashboard product |
| --- | --- | --- | --- | --- | --- | --- |
| J1 | A | yes | required | required | not stated | not stated |
| J2 | A | yes | required | not stated | preferred | not stated |
| J3 | B | yes | required | required | not stated | not stated |
| J4 | C | yes | required | not stated | preferred | not stated |
| J5 | D | yes | not stated | required | not stated | not stated |
| J6 | E | yes | not stated | not stated | preferred | context |
| J7 | unknown | no | unknown | unknown | unknown | unknown |

"Not stated" means this fictional text does not say. It does not mean the skill is absent from the employer's real work.

| Job | Employer | Exact fictional sentence | Skill name | Class | Duty | Note |
| --- | --- | --- | --- | --- | --- | --- |
| J1 | A | You must use SQL to filter and join sales tables. | SQL | required | Filter and join tables | "Must" means required. |
| J1 | A | You must use a spreadsheet to chart monthly results. | spreadsheets | required | Chart monthly results | Second duty in the same listing. |
| J2 | A | SQL is required for reporting. | SQL | required | Write a report query | The text says required. |
| J2 | A | Python is preferred for extra checks. | Python | preferred | Extra checks | Preferred is not required. |
| J3 | B | You must use SQL and spreadsheets to reconcile order totals. | SQL | required | Reconcile totals | One sentence can hold two skills. |
| J3 | B | You must use SQL and spreadsheets to reconcile order totals. | spreadsheets | required | Reconcile totals | Do not drop the second skill. |
| J4 | C | SQL is required. | SQL | required | Query the data | Required stands alone. |
| J4 | C | Python is preferred and is not required. | Python | preferred | None as a must | The text refuses a required label. |
| J5 | D | You must clean a table in a spreadsheet and chart it. | spreadsheets | required | Clean and chart | SQL is not in the text. Do not add it. |
| J6 | E | Python is preferred. | Python | preferred | None as a must | Preferred only. |
| J6 | E | The team uses a dashboard product for internal charts. | dashboard product | context | Not a test for the applicant | Do not label this as a required skill. |
| J7 | unknown | No description text. | none | unknown | unknown | Gap. Do not enter zero skills. |

| Skill | Class | Listings | Listing count out of 6 | Employers | Employer count out of 5 |
| --- | --- | --- | --- | --- | --- |
| SQL | required | J1, J2, J3, J4 | 4 | A, B, C | 3 |
| Spreadsheets | required | J1, J3, J5 | 3 | A, B, D | 3 |
| Python | preferred | J2, J4, J6 | 3 | A, C, E | 3 |
| Dashboard product | context | J6 | 1 | E | 1 |

Required SQL is in four of six listings. Those listings belong to three of five employers: A, B, and C. J1 and J2 are both from Employer A. The fourth SQL listing adds a listing. It does not add an employer.

Required spreadsheet work is in three of six listings. Those listings belong to three of five employers: A, B, and D. Employer D requires spreadsheets and does not mention SQL.

Preferred Python is in three of six listings. Those listings belong to three of five employers: A, C, and E. Python is not required in this table.

The dashboard product is context in J6 only. None of the six listings marks it required. That "none" is a label count for these six texts. It is not a country result. J7 stays unknown, so it is not part of that "none."

A keyword rank would put SQL first, because four is more than three. It would then tie spreadsheets with Python. It might also keep the dashboard product. That rank is the wrong study order.

Employer count makes SQL, spreadsheets, and Python even, at three employers each. Requirement class then drops Python behind the two required skills. It also drops the dashboard product out of the study list. The extra SQL listing is Employer A twice. It should not put SQL alone ahead of spreadsheet work.

Do not turn four of six into a rate for all jobs in a country. Four of six describes only this fictional set.

## 6. Mark the proof you have

A skill name on a résumé is not proof. Proof is finished work that another person can inspect. A query can be proof. A cleaned table can be proof. A chart with a written decision can be proof.

Mark each repeated duty present, partial, or absent. Present means inspected proof exists. Partial means some of the duty is shown and some is missing. Absent means no proof is shown. Do not invent a hire score. Do not predict interviews.

In this fiction, the learner can write a basic SQL filter. A filter keeps some rows and drops others. That proof is present. The learner has no finished join. A join links two tables by a shared key. That proof is absent. The learner has no report whose totals were reconciled. Reconcile means the output totals match the input totals. That proof is absent. A spreadsheet chart is also absent. Python is not the first gap, because its class is preferred.

| Duty | Why it is in the sample | Proof in this fiction | Mark |
| --- | --- | --- | --- |
| SQL filter | Required in SQL listings | Basic filter can be written | present |
| SQL join | J1 says filter and join. The employer is A. | No finished join | absent |
| Reconcile totals | J3 requires this duty. The employer is B. | No reconciled report | absent |
| Spreadsheet chart | The chart duty appears in J1 and J5. The employers are A and D. | No finished chart | absent |
| Python | Preferred only | Not chosen as the first gap | later |
| Dashboard product | Context only | Not a required duty | leave out |

Skill breadth is not specific duty breadth. SQL skills span 3 employers. Spreadsheet skills span 3 employers. The join duty appears in J1 at employer A. The reconciliation duty appears in J3 at employer B. The chart duty appears in J1 and J5 at employers A and D. Together, this explicit duty evidence spans employers A, B, and D. It does not span employer C. These duties do not each span 3 employers.

More filter practice would repeat proof that is already present. The missing required proof is the join, the reconciled totals, and the chart. The first project must cover those gaps. Do not let J2 alone turn Python into the whole plan.

## 7. Choose one project

In this fiction, use the SQL join, the reconciliation, and the spreadsheet chart. This set is a deliberate combination. The three duties fit one job of work. All three are tied to required text. The join duty appears in J1 at employer A. The reconciliation duty appears in J3 at employer B. The chart duty appears in J1 and J5 at employers A and D. Together, the explicit duty evidence spans employers A, B, and D. It does not span employer C. SQL skills span 3 employers. Spreadsheet skills span 3 employers. Skill breadth is not specific duty breadth. These duties do not each span 3 employers.

A useful project proves that work. A long list of tools does not make it useful. Name the skills you must practice first. Practice a basic join and a spreadsheet sum first. Do not add Python until you can explain the SQL and spreadsheet result.

An acceptance check is a test that says the project is done. The checks below are a plan. They are not measured learner results. This article did not run a query. The totals below are a hand check of the fixture.

A fixture is a small set of made-up rows used for the test. Keep the input rows unchanged.

Customer rows: 4 customer IDs.

| customer_id | customer_name |
| --- | --- |
| C1 | North Shop |
| C2 | East Shop |
| C3 | West Shop |
| C4 | South Shop |

Order rows: 10 orders.

| order_id | customer_id | order_month | amount |
| --- | --- | --- | --- |
| O1 | C1 | January | 10 |
| O2 | C1 | January | 20 |
| O3 | C2 | January | 15 |
| O4 | C2 | February | 25 |
| O5 | C3 | February | 30 |
| O6 | C3 | February | 5 |
| O7 | C1 | February | 40 |
| O8 | CX | January | 12 |
| O9 | C2 | January | 8 |
| O10 | CX | February | 18 |

Read these as two different counts. The customer table has 4 IDs: C1, C2, C3, and C4. The orders use 4 different customer keys: C1, C2, C3, and CX. Three of those order keys are known customer IDs. One order key is unmatched. The unmatched key is CX. C4 has no orders. CX is not the same fact as C4.

By eye, each customer ID appears once. The expected duplicate customer-ID count is 0. Each order ID also appears once. This is a hand reading of the fixture. It is not a query result.

Hand totals, if every order stays in the monthly table:

- January amounts are 10, 20, 15, 12, and 8. Their sum is 65.
- February amounts are 25, 30, 5, 40, and 18. Their sum is 118.
- The month sums are 65 and 118. Their sum is 183.
- The ten order amounts also sum to 183.
- CX amounts are 12 and 18. Their sum is 30.
- The matched amount is 183 minus 30, which is 153.

A correct monthly table that includes every order should show January 65, February 118, and a total of 183. The chart should show those two month amounts. This article does not include a finished chart. You build the chart in a spreadsheet.

The unmatched orders are O8 and O10. Both use CX. A correct unmatched-key test should point to those two rows.

Project brief for this fiction:

- Input: the 10 order rows and 4 customer rows above.
- Output: a monthly sales table, a spreadsheet chart, and two written findings.
- Method: link orders to customers, mark CX, and sum amount by month.
- Quality check: add the input by hand and match 183 to the monthly table.
- Show: the query text, the chart, the unmatched key, and one limit.

Two findings should be possible from the fixture. First, CX is not in the customer table, and its amount is 30. Second, C4 has no orders. Those findings are the expected explanation. They are not results from a run.

Planned query text for the monthly table. This article did not run it.

```sql
SELECT o.order_month, SUM(o.amount) AS month_amount
FROM orders AS o
GROUP BY o.order_month
```

7. Choose one project

Planned query text for unmatched order keys. This article did not run it.

```sql
SELECT o.order_id, o.customer_id, o.amount
FROM orders AS o
LEFT JOIN customers AS c
  ON c.customer_id = o.customer_id
WHERE c.customer_id IS NULL
```

7. Choose one project

Use these acceptance checks:

1. The original 10 order rows and 4 customer rows stay unchanged.
2. The work reports 10 orders.
3. The work reports 4 customer IDs.
4. The work reports 4 different customer keys on the orders.
5. Those 4 keys are named as 3 known IDs plus the unmatched key CX.
6. The note explains CX and does not confuse it with C4.
7. A hand check shows order amounts sum to 183, and the monthly table also sums to 183.
8. The query text and the chart are both shown.
9. The learner explains one limit.

One clear limit is enough. For example, the monthly total includes the unmatched 30, while the matched total is 153. Another true limit is that this project does not prove Python. A third is that six fictional listings are not a national result. Any one of these limits can pass the last check.

## 8. Order the plan

Put the work in four parts. Do not start with the preferred skill.

Part one is practice you do first. Practice one join on this fixture. Practice one spreadsheet sum.

Part two is the combined project. Build the monthly table. Build the chart. Write the two findings.

Part three is review. Another reader uses the acceptance checks. The reader does not need to trust a score. The reader can count 10 orders, count 4 customer IDs, find CX, and add the amounts.

Part four is the explanation. Explain the unmatched key. Explain one limit.

The rank for this fiction is short. First, do the join, the reconciliation, and the chart. Those duties are required, and the proof is missing. This project is a deliberate combination. The explicit duty evidence spans employers A, B, and D. It does not span employer C. These duties do not each span 3 employers. SQL skills span 3 employers. Spreadsheet skills span 3 employers. Skill breadth is not specific duty breadth. Next, review that project with the checks. Only after you can explain that work, practice Python. Leave the dashboard product out of the skill plan.

You set the time boxes. A time box is the time you choose to spend. It is not a promise that you will master the skill. In this fictional plan, use one sitting for practice. Use one sitting for the project. Use one sitting for review and explanation.

If you change the role, the level, or the market, collect a new sample. Use the same rules. Do not reuse this fictional rank for a different role.

## Next action

Choose one required duty that repeats across different employers in your own full-text sample. Write one acceptance check for a project that proves that duty, with input counts a second person can test. Collect the job text with the [LinkedIn Jobs Actor](https://apify.com/chronometrica/linkedin-jobs-scraper). Start from the saved [skills demand Task](https://apify.com/chronometrica/linkedin-jobs-scraper/examples/linkedin-skills-demand). Replace the three mixed roles with one role and one location, and keep a small row cap.

## Sources

- [LinkedIn Jobs Actor](https://apify.com/chronometrica/linkedin-jobs-scraper)
- [LinkedIn Job Description Skills Demand Dataset](https://apify.com/chronometrica/linkedin-jobs-scraper/examples/linkedin-skills-demand)
- [Recent data science graduate seeking advice](https://www.reddit.com/r/FresherTechJobsIndia/comments/1ncge8k/recent_data_science_graduate_seeking_advice/)