-
Notifications
You must be signed in to change notification settings - Fork 7
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
ebc88fa
commit 5802188
Showing
5 changed files
with
126 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,6 @@ | ||
[tool.poetry] | ||
name = "staffspy" | ||
version = "0.2.16" | ||
version = "0.2.17" | ||
description = "Staff scraper library for LinkedIn" | ||
authors = ["Cullen Watson <[email protected]>"] | ||
readme = "README.md" | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
import json | ||
import re | ||
from datetime import datetime as dt | ||
|
||
from staffspy.utils.exceptions import TooManyRequests | ||
from staffspy.utils.models import Comment | ||
|
||
from staffspy.utils.utils import logger | ||
|
||
|
||
class CommentFetcher: | ||
|
||
def __init__(self, session): | ||
self.session = session | ||
self.endpoint = "https://www.linkedin.com/voyager/api/graphql?queryId=voyagerSocialDashComments.200c8ad7e1ad32ba4e5cc827ab5c3193&queryName=SocialDashCommentsBySocialDetail&variables=(origins:List(),sortOrder:REVERSE_CHRONOLOGICAL,count:100,socialDetailUrn:urn%3Ali%3Afsd_socialDetail%3A%28urn%3Ali%3Aactivity%3A{post_id}%2Curn%3Ali%3Aactivity%3A{post_id}%2Curn%3Ali%3AhighlightedReply%3A-%29,start:{start})" | ||
self.post_id = None | ||
self.num_commments = 100 | ||
|
||
def fetch_comments(self, post_id: str): | ||
all_comments = [] | ||
self.post_id = post_id | ||
|
||
for i in range(0, 100_000, self.num_commments): | ||
logger.info(f"Fetching comments for post {post_id}, start {i}") | ||
|
||
ep = self.endpoint.format(post_id=post_id, start=i) | ||
res = self.session.get(ep) | ||
logger.debug(f"comments info, status code - {res.status_code}") | ||
|
||
if res.status_code == 429: | ||
return TooManyRequests("429 Too Many Requests") | ||
if not res.ok: | ||
logger.debug(res.text[:200]) | ||
return False | ||
try: | ||
comments_json = res.json() | ||
except json.decoder.JSONDecodeError: | ||
logger.debug(res.text[:200]) | ||
return False | ||
|
||
comments, num_results = self.parse_comments(comments_json) | ||
all_comments.extend(comments) | ||
if not num_results: | ||
break | ||
|
||
return all_comments | ||
|
||
def parse_comments(self, comments_json: dict): | ||
"""Parse the comment data from the employee profile.""" | ||
comments = [] | ||
for element in ( | ||
results := comments_json.get("data", {}) | ||
.get("socialDashCommentsBySocialDetail", {}) | ||
.get("elements", []) | ||
): | ||
internal_profile_id = (commenter := element["commenter"])[ | ||
"commenterProfileId" | ||
] | ||
name = commenter["title"]["text"] | ||
linkedin_id_match = re.search("/in/(.+)", commenter["navigationUrl"]) | ||
linkedin_id = linkedin_id_match.group(1) if linkedin_id_match else None | ||
|
||
commentary = element.get("commentary", {}).get("text", "") | ||
comment = Comment( | ||
post_id=self.post_id, | ||
internal_profile_id=internal_profile_id, | ||
public_profile_id=linkedin_id, | ||
name=name, | ||
text=commentary, | ||
created_at=dt.utcfromtimestamp(element["createdAt"] / 1000), | ||
) | ||
comments.append(comment) | ||
|
||
return comments, len(results) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters