ExtractHyperlinksFromOfficeFiles
Extracts hyperlinks from office files. Supported file types are: xlsx, docx, pptx.
- Type
- python
- Pack
- CommonScripts
Source
import os
import zipfile
from io import BytesIO
import demistomock as demisto # noqa: F401
import openpyxl
import pandas as pd
from CommonServerPython import * # noqa: F401
from docx import Document
from docx.opc.constants import RELATIONSHIP_TYPE as RT
from pptx import Presentation
from pptx.enum.shapes import MSO_SHAPE_TYPE
def extract_hyperlinks_from_xlsx(file_path: str) -> Set:
with zipfile.ZipFile(file_path, "r") as zf:
xmls = [zf.read(fn) for fn in zf.infolist() if fn.filename.startswith("xl/drawings/_rels/")]
urls = set()
for xml_data in xmls:
# Wrap bytes in BytesIO for compatibility with pandas 2.x
df = pd.read_xml(BytesIO(xml_data))
if "TargetMode" in df.columns:
filtered_df = df.loc[df["TargetMode"].eq("External"), "Target"]
urls |= set(filtered_df)
wb = openpyxl.load_workbook(file_path)
for sheet in wb:
for row in sheet.iter_rows():
for cell in row:
if cell.hyperlink:
urls.add(cell.hyperlink.target)
return urls
def extract_hyperlinks_from_docx(file_path: str) -> Set:
doc = Document(file_path)
links = set()
for rel in doc.part.rels.values():
if rel.reltype == RT.HYPERLINK and rel.is_external:
links.add(rel._target)
return links
def extract_hyperlinks_from_pptx(file_path: str) -> Set:
prs = Presentation(file_path)
links = set()
for slide in prs.slides:
for shape in slide.shapes:
if shape.has_text_frame:
for paragraph in shape.text_frame.paragraphs:
for run in paragraph.runs:
if run.hyperlink and run.hyperlink.address:
links.add(run.hyperlink.address)
if shape.shape_type == MSO_SHAPE_TYPE.GROUP: # pylint: disable=E1101
group_shape = shape
for s in group_shape.shapes:
if s.click_action and s.click_action.hyperlink.address:
links.add(s.click_action.hyperlink.address)
elif shape.click_action and shape.click_action.hyperlink.address:
links.add(shape.click_action.hyperlink.address)
return links
def extract_hyperlink_by_file_type(file_name: str, file_path: str) -> CommandResults:
if file_name.lower().endswith(".xlsx"):
result = extract_hyperlinks_from_xlsx(file_path)
elif file_name.lower().endswith(".docx"):
result = extract_hyperlinks_from_docx(file_path)
elif file_name.lower().endswith(".pptx"):
result = extract_hyperlinks_from_pptx(file_path)
else:
raise ValueError("Unsupported file type. Supported types are: 'xlsx, docx, pptx'")
if result:
urls_str = "\n".join(result)
hr = f"### Extracted Hyperlinks\n\n{urls_str}"
else:
hr = "**No hyperlinks.**"
output = [{"URL": url, "FileName": file_name} for url in result]
return CommandResults(
outputs=output,
outputs_prefix="ExtractedHyperLink",
outputs_key_field=["URL", "FileName"],
readable_output=hr,
raw_response=list(result),
)
def main(): # pragma: no cover
try:
entry_id = demisto.args().get("entry_id")
file_result = demisto.getFilePath(entry_id)
if not file_result:
raise ValueError(f"Couldn't find entry id: {entry_id}")
file_name = os.path.basename(file_result.get("name", ""))
file_path = file_result.get("path")
os.rename(f"./{file_path}", file_name)
return_results(extract_hyperlink_by_file_type(file_name=file_name, file_path=os.path.realpath(file_name)))
except Exception as ex:
return_error(f"Failed to execute ExtractHyperlinksFromOfficeFiles. Error: {ex!s}")
if __name__ in ("__main__", "__builtin__", "builtins"):
main()
README
Extract hyperlinks from office files. Supported file types are: xlsx, docx, pptx.
Script Data
| Name | Description |
|---|---|
| Script Type | python3 |
| Cortex XSOAR Version | 5.5.0 |
Inputs
| Argument Name | Description |
|---|---|
| entry_id | The entry id of the file to extract hyperlinks from. |
Outputs
| Path | Description | Type |
|---|---|---|
| ExtractedHyperLink.URL | The extracted hyperlinks URL. | String |
| ExtractedHyperLink.FileName | The office file that the hyperlinks extracted from. | String |
Script Examples
Example command
!ExtractHyperlinksFromOfficeFiles entry_id=1249@93725c86-540d-4ee4-8728-f0ab82b1cb46
Context Example
{
"ExtractedHyperLink": {
"FileName": "Link.docx",
"URL": "https://www.paloaltonetworks.com/"
}
}
Human Readable Output
Extracted hyperlinks are
https://www.paloaltonetworks.com/