Vaibhav Pande
Vaibhav Pande

Reputation: 1

UnicodeEncodeError: 'ascii' codec can't encode character '\u20b9' in position 248: ordinal not in range(128)

I tried making a web scraper to track amazon prices and send me an email alert whenever there is some change or fluctuation in the price but this is the error I'm getting, I'm pretty new to this.

error in detail :

    Traceback (most recent call last):
  File "/Users/vaibhav/Desktop/labai/scraper.py", line 53, in <module>
    check_price()
  File "/Users/vaibhav/Desktop/labai/scraper.py", line 20, in check_price
    send_mail()
  File "/Users/vaibhav/Desktop/labai/scraper.py", line 45, in send_mail
    msg
  File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/smtplib.py", line 855, in sendmail
    msg = _fix_eols(msg).encode('ascii')
UnicodeEncodeError: 'ascii' codec can't encode character '\u20b9' in position 248: ordinal not in range(128)

Python code I wrote

    import requests
    from bs4 import BeautifulSoup
    import smtplib


    URL = 'https://www.amazon.in/Nokia-Designer-Protective-Printed-Doesnt/dp/B078MFZS9V/ref=bbp_bb_a77114_st_KIqx_w_1?psc=1&smid=A2V1Y4Y0T37MVF'
    headers = {example user agent}


    def check_price():
        page = requests.get(URL,headers = headers)

    soup = BeautifulSoup(page.content,'html.parser')

    title = soup.find(id="productTitle").get_text()
    price = soup.find(id="priceblock_ourprice").get_text()
    converted_price = float(price[2:5])

    if(converted_price<400):
        send_mail()

    print(title.strip())
    print(converted_price)


    if(converted_price>300):
        send_mail()

def send_mail():
    server = smtplib.SMTP('smtp.gmail.com', 587)
    server.ehlo()
    server.starttls()
    server.ehlo()

    server.login(''example@exampleemail'','examplepass')

    subject = 'Price fell down'
    body =  'Check the amazon link  https://www.amazon.in/dp/B07XVKG5XV?aaxitk=Afmq.hE.Dq.i9ttZqy2U9g&pd_rd_i=B07XVKG5XV&pf_rd_p=2e3653de-1bdf-402d-9355-0b76590c54fe&hsa_cr_id=4398426540602&sb-ci-n=price&sb-ci-v=64%2C899.00&sb-ci-m=₹'

    msg = f"Subject = {subject}\n\n{body}"

    server.sendmail(
        'example@exampleemail',
        'example@exampleemail',
        msg
    )

    print('HEY MAIL HAS BEEN SENT')

    server.quit()


check_price()

Upvotes: 0

Views: 1634

Answers (1)

kopecs
kopecs

Reputation: 1731

This is a result of the currency symbol ₹ for the rupee not being able to be encoded in ASCII. You likely instead want to enable UTF-8 (or some other unicode encoding) for smtplib. The easiest way to do so looks to be using the email (link is to examples) module.

import smtplib
from email.mime.text import MIMEText

text_type = 'plain' # or 'html'
text = 'Your message body'
msg = MIMEText(text, text_type, 'utf-8')
msg['Subject'] = 'Test Subject'
msg['From'] = gmail_user
msg['To'] = '[email protected],[email protected]'
server = smtplib.SMTP_SSL('smtp.gmail.com', 465)
server.login(gmail_user, gmail_password)
server.send_message(msg)
# or server.sendmail(msg['From'], msg['To'], msg.as_string())
server.quit()

Code copied from this answer.

Note that in MIMEText we use 'utf-8'. This is what allows us to encode the INR currency symbol.

Upvotes: 3

Related Questions