Skip to content

Create crawler.py#1

Open
akshayutture wants to merge 1 commit into
masterfrom
test
Open

Create crawler.py#1
akshayutture wants to merge 1 commit into
masterfrom
test

Conversation

@akshayutture

@akshayutture akshayutture commented Apr 4, 2024

Copy link
Copy Markdown
Owner

Summary by CodeRabbit

  • New Features
    • Implemented a web crawler to scrape and store product data, with output available in CSV format.

@coderabbitai

coderabbitai Bot commented Apr 4, 2024

Copy link
Copy Markdown
Walkthrough

Walkthrough

The update introduces a web crawler script named crawler.py designed for scraping product information from websites. This crawler gathers product data, organizes it into a structured format, and then exports this collected data into a CSV file. This enhancement focuses on automating the process of data collection and storage, streamlining the task of aggregating product details from online sources.

Changes

File(s) Summary
crawler.py Added a web crawler for scraping product data and exporting to CSV.

Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

Share

Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai generate interesting stats about this repository and render them as a table.
    • @coderabbitai show all the console.log statements in this repository.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (invoked as PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger a review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai help to get help.

Additionally, you can add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.

CodeRabbit Configration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/coderabbit-overrides.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@akshayutture

Copy link
Copy Markdown
Owner Author

@coderabbitai review

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 5

Review Status

Configuration used: CodeRabbit UI

Commits Files that changed from the base of the PR and between 0b1daf2 and 1fcdbe3.
Files selected for processing (1)
  • crawler.py (1 hunks)
Additional comments not posted (1)
crawler.py (1)

16-38: Implement a mechanism to limit the depth of the crawl to prevent infinite loops in case of cyclic links.

Comment thread crawler.py
Comment on lines +3 to +5
import requests
from bs4 import BeautifulSoup
import csv

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider grouping imports according to PEP 8 standards.

- import requests
- from bs4 import BeautifulSoup
- import csv
+ import csv
+ import requests
+ from bs4 import BeautifulSoup

Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation.

Suggested change
import requests
from bs4 import BeautifulSoup
import csv
import csv
import requests
from bs4 import BeautifulSoup

Comment thread crawler.py
Comment on lines +16 to +38
while len(urls) != 0:
# get the page to visit from the list
current_url = urls.pop()

# crawling logic
response = requests.get(current_url)
soup = BeautifulSoup(response.content, "html.parser")

link_elements = soup.select("a[href]")

for link_element in link_elements:
url = link_element["href"]
if "https://scrapeme.live/shop" in url:
urls.append(url)

# if current_url is product page
product = {}
product["url"] = current_url
product["image"] = soup.select_one(".wp-post-image")["src"]
product["name"] = soup.select_one(".product_title").text()
product["price"] = soup.select_one(".price")

products.append(product)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add error handling for network requests and data extraction.

+ try:
      response = requests.get(current_url)
      soup = BeautifulSoup(response.content, "html.parser")
+ except requests.RequestException as e:
+     print(f"Request error: {e}")
+     continue
+ try:
      product["image"] = soup.select_one(".wp-post-image")["src"]
      product["name"] = soup.select_one(".product_title").text()
      product["price"] = soup.select_one(".price")
+ except AttributeError as e:
+     print(f"Data extraction error: {e}")
+     continue

Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation.

Suggested change
while len(urls) != 0:
# get the page to visit from the list
current_url = urls.pop()
# crawling logic
response = requests.get(current_url)
soup = BeautifulSoup(response.content, "html.parser")
link_elements = soup.select("a[href]")
for link_element in link_elements:
url = link_element["href"]
if "https://scrapeme.live/shop" in url:
urls.append(url)
# if current_url is product page
product = {}
product["url"] = current_url
product["image"] = soup.select_one(".wp-post-image")["src"]
product["name"] = soup.select_one(".product_title").text()
product["price"] = soup.select_one(".price")
products.append(product)
while len(urls) != 0:
# get the page to visit from the list
current_url = urls.pop()
# crawling logic
try:
response = requests.get(current_url)
soup = BeautifulSoup(response.content, "html.parser")
except requests.RequestException as e:
print(f"Request error: {e}")
continue
link_elements = soup.select("a[href]")
for link_element in link_elements:
url = link_element["href"]
if "https://scrapeme.live/shop" in url:
urls.append(url)
# if current_url is product page
product = {}
product["url"] = current_url
try:
product["image"] = soup.select_one(".wp-post-image")["src"]
product["name"] = soup.select_one(".product_title").text()
product["price"] = soup.select_one(".price")
except AttributeError as e:
print(f"Data extraction error: {e}")
continue
products.append(product)

Comment thread crawler.py
product["url"] = current_url
product["image"] = soup.select_one(".wp-post-image")["src"]
product["name"] = soup.select_one(".product_title").text()
product["price"] = soup.select_one(".price")

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ensure that the .text() method is called for the "price" element to extract its text content.

- product["price"] = soup.select_one(".price")
+ product["price"] = soup.select_one(".price").text()

Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation.

Suggested change
product["price"] = soup.select_one(".price")
product["price"] = soup.select_one(".price").text()

Comment thread crawler.py
Comment on lines +41 to +46
with open('products.csv', 'w') as csv_file:
writer = csv.writer(csv_file)

# populating the CSV
for product in products:
writer.writerow(product.values())

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Specify the newline parameter in open to prevent blank lines in the CSV file on certain platforms.

- with open('products.csv', 'w') as csv_file:
+ with open('products.csv', 'w', newline='') as csv_file:

Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation.

Suggested change
with open('products.csv', 'w') as csv_file:
writer = csv.writer(csv_file)
# populating the CSV
for product in products:
writer.writerow(product.values())
with open('products.csv', 'w', newline='') as csv_file:
writer = csv.writer(csv_file)
# populating the CSV
for product in products:
writer.writerow(product.values())

Comment thread crawler.py
Comment on lines +16 to +30
while len(urls) != 0:
# get the page to visit from the list
current_url = urls.pop()

# crawling logic
response = requests.get(current_url)
soup = BeautifulSoup(response.content, "html.parser")

link_elements = soup.select("a[href]")

for link_element in link_elements:
url = link_element["href"]
if "https://scrapeme.live/shop" in url:
urls.append(url)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider checking for duplicate URLs before appending to avoid re-visiting the same page.

+ if url not in urls:
      urls.append(url)

Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation.

Suggested change
while len(urls) != 0:
# get the page to visit from the list
current_url = urls.pop()
# crawling logic
response = requests.get(current_url)
soup = BeautifulSoup(response.content, "html.parser")
link_elements = soup.select("a[href]")
for link_element in link_elements:
url = link_element["href"]
if "https://scrapeme.live/shop" in url:
urls.append(url)
while len(urls) != 0:
# get the page to visit from the list
current_url = urls.pop()
# crawling logic
response = requests.get(current_url)
soup = BeautifulSoup(response.content, "html.parser")
link_elements = soup.select("a[href]")
for link_element in link_elements:
url = link_element["href"]
if "https://scrapeme.live/shop" in url:
if url not in urls:
urls.append(url)

@akshayutture

Copy link
Copy Markdown
Owner Author

augment review

@augmentcode augmentcode Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review completed. 3 suggestions posted.

Comment augment review to trigger a new review at any time.

Comment thread crawler.py
@@ -0,0 +1,46 @@
# Simple web crawler

import requests

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All code in this file is indented at the top level (e.g., the imports), which will raise IndentationError: unexpected indent and prevent the script from running.

🤖 Was this useful? React with 👍 or 👎

Comment thread crawler.py
product = {}
product["url"] = current_url
product["image"] = soup.select_one(".wp-post-image")["src"]
product["name"] = soup.select_one(".product_title").text()

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

soup.select_one(".product_title").text() will crash because BeautifulSoup’s Tag.text is a property (and get_text() is the method), so calling .text() attempts to call a string.

🤖 Was this useful? React with 👍 or 👎

Comment thread crawler.py
# if current_url is product page
product = {}
product["url"] = current_url
product["image"] = soup.select_one(".wp-post-image")["src"]

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The “if current_url is product page” extraction runs for every visited URL; on non-product pages select_one(...) can be None, so ...["src"] / later attribute access will raise at runtime.

🤖 Was this useful? React with 👍 or 👎

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant