[mypy] Fix web_programming directory
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index f544c02b1c35..76c6357fe0ca 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -23,7 +23,7 @@ jobs:
           python -m pip install mypy pytest-cov -r requirements.txt
       # FIXME: #4052 fix mypy errors in the exclude directories and remove them below
       - run: mypy --ignore-missing-imports
-          --exclude '(arithmetic_analysis|ciphers|conversions|data_structures|digital_image_processing|dynamic_programming|graphs|hashes|linear_algebra|maths|matrix|other|project_euler|scripts|searches|strings|web_programming*)/$' .
+          --exclude '(arithmetic_analysis|ciphers|conversions|data_structures|digital_image_processing|dynamic_programming|graphs|hashes|linear_algebra|maths|matrix|other|project_euler|scripts|searches|strings*)/$' .
       - name: Run tests
         run: pytest --doctest-modules --ignore=project_euler/ --ignore=scripts/ --cov-report=term-missing:skip-covered --cov=. .
       - if: ${{ success() }}
diff --git a/web_programming/currency_converter.py b/web_programming/currency_converter.py
index 6aed2a5578a5..447595b0b646 100644
--- a/web_programming/currency_converter.py
+++ b/web_programming/currency_converter.py
@@ -9,7 +9,7 @@
 
 URL_BASE = "https://www.amdoren.com/api/currency.php"
 TESTING = os.getenv("CI", False)
-API_KEY = os.getenv("AMDOREN_API_KEY")
+API_KEY = os.getenv("AMDOREN_API_KEY", "")
 if not API_KEY and not TESTING:
     raise KeyError("Please put your API key in an environment variable.")
 
diff --git a/web_programming/emails_from_url.py b/web_programming/emails_from_url.py
index 01dee274f015..0571ac3313a3 100644
--- a/web_programming/emails_from_url.py
+++ b/web_programming/emails_from_url.py
@@ -8,18 +8,19 @@
 
 import re
 from html.parser import HTMLParser
+from typing import Optional
 from urllib import parse
 
 import requests
 
 
 class Parser(HTMLParser):
-    def __init__(self, domain: str):
-        HTMLParser.__init__(self)
-        self.data = []
+    def __init__(self, domain: str) -> None:
+        super().__init__()
+        self.urls: list[str] = []
         self.domain = domain
 
-    def handle_starttag(self, tag: str, attrs: str) -> None:
+    def handle_starttag(self, tag: str, attrs: list[tuple[str, Optional[str]]]) -> None:
         """
         This function parse html to take takes url from tags
         """
@@ -29,10 +30,10 @@ def handle_starttag(self, tag: str, attrs: str) -> None:
             for name, value in attrs:
                 # If href is defined, and not empty nor # print it.
                 if name == "href" and value != "#" and value != "":
-                    # If not already in data.
-                    if value not in self.data:
+                    # If not already in urls.
+                    if value not in self.urls:
                         url = parse.urljoin(self.domain, value)
-                        self.data.append(url)
+                        self.urls.append(url)
 
 
 # Get main domain name (example.com)
@@ -59,7 +60,7 @@ def get_sub_domain_name(url: str) -> str:
     return parse.urlparse(url).netloc
 
 
-def emails_from_url(url: str = "https://github.com") -> list:
+def emails_from_url(url: str = "https://github.com") -> list[str]:
     """
     This function takes url and return all valid urls
     """
@@ -78,7 +79,7 @@ def emails_from_url(url: str = "https://github.com") -> list:
 
         # Get links and loop through
         valid_emails = set()
-        for link in parser.data:
+        for link in parser.urls:
             # open URL.
             # read = requests.get(link)
             try:

A subtask of #4052

### **Describe your change:**



* [ ] Add an algorithm?
* [x] Fix a bug or typo in an existing algorithm?
* [ ] Documentation change?

### **Checklist:**
* [x] I have read [CONTRIBUTING.md](https://github.com/TheAlgorithms/Python/blob/master/CONTRIBUTING.md).
* [x] This pull request is all my own work -- I have not plagiarized.
* [x] I know that pull requests will not be merged if they fail the automated tests.
* [x] This PR only changes one algorithm file.  To ease review, please open separate PRs for separate algorithms.
* [x] All new Python files are placed inside an existing directory.
* [x] All filenames are in all lowercase characters with no spaces or dashes.
* [x] All functions and variable names follow Python naming conventions.
* [x] All function parameters and return values are annotated with Python [type hints](https://docs.python.org/3/library/typing.html).
* [x] All functions have [doctests](https://docs.python.org/3/library/doctest.html) that pass the automated testing.
* [x] All new algorithms have a URL in its comments that points to Wikipedia or other similar explanation.
* [x] If this pull request resolves one or more open issues then the commit message contains `Fixes: #{$ISSUE_NO}`.
