Home>

Many people like to visit the library,Borrow books from time to time,But each book may only be borrowed for two months,If it is not overdue, a corresponding penalty will be imposed! Why not write a script to notify yourself that your books are overdue?So much nonsense,Let's get into the subject! !! !!

I. Simulated Login Library Management System

We can first look at the login page (many schools have these management system pages that are very low):

There are two ways to simulate logging into the library:

1. Construct a login form for simulated login

This method of simulated login seems to be very reliable,But sometimes it ’s difficult to get the verification code.If simple website,Some will use the current timestamp to construct the verification code,This is easy to observe from the web page,However, for example, the website that we are trying to log in to this time seems to be unable to do so.Because it is a verification code link generated randomly using the math function in the JavaScript standard library,You can observe the code at the verification code from the following picture:

It usesmath.random () function returns a floating-point value pseudo random number of [0-1) (greater than or equal to 0, less than 1)Ok! Let's switch to a simpler way to simulate login!

2. Login to the library via cookies

Cookie refers to the data (usually encrypted) stored on the user's local terminal by some websites in order to identify the user and track the session.

Here we userequests library to simulate the login process,We have a question before that,How do I get cookies??If you are using Google Chrome,Then you can see the content of a cookie in the following picture by pressing f12, this is what i want:

Let's analyze it again in the previous figure.I hope you can read it patiently:

From the picture we know that we can get the borrowing date and due date,After getting the date, compare the due date with the current date,It can be concluded whether the result is overdue.Not much to say, let's post the code first:

import requests
session=requests.session () #The session object allows you to persist certain parameters across requests,It will also keep cookies between all requests made by the same session instance
session.headers={
  "user-agent":"mozilla/5.0 (windows nt 10.0;wow64) applewebkit/537.36 (khtml, like gecko) chrome/51.0.2704.84 safari/537.36",  "cookie":"asp.net_sessionid=1qri0rmoylpyrs45rurzme55;hm_lvt_ed06d5e5f94d85932b82e4aac94d0c68=1467535679, 1469713840;hm_lpvt_ed06d5e5f94d85932b82e4aac94d0c1vf1qfd1c6d1d1c1c1c1c1c1c1c1c1c1c1c0c1c1
}

The above code usesrequests session object to save cookies, if we need to jump to another page,We don't have to simulate login every time,Because cookies have saved our login status.

Is there any doubt?Did n’t you mean to simulate login??Why is there no such process??

In fact, the cookie in our code above has saved our login status,It is equivalent to that we have simulated login,Isn't it much simpler to simulate login like this?But the disadvantage is that we need to manually enter it on the login page,Then find the cookie from the login page and paste it into the code

Obtaining information about borrowed books

By analyzing the page,We can usebeautifulsoup to extract what we need,What we need is the barcode, title and author of the book, borrowing date, due date,In fact, we just need to return the date.But for later needs,First get all the information of the book and save it in the database:

Defines a database operation functionfor easy recall

def get_mysql ():
  conn=pymysql.connect (host="localhost", user="root", passwd="2014081029", db="mysql", charset="utf8") #user is the name of the database,passwd is the database password,Generally define the character set as utf8, otherwise it is easy to encounter encoding problems when stored in the database
  cur=conn.cursor () #Get operation cursor
  cur.execute ("use book") #use the book database
  return (cur, conn)

Define a function to get the book information and save:

def get_book_name (book_url):
  html=session.get (book_url, cookies=cookie, headers=headers) .content.decode ("utf-8")
  soup=beautifulsoup (html, "lxml")
  book_bar=[] #barcode list of books,Used to determine whether the books to be stored in the database already exist
  cur, conn=get_mysql ()
  sql="select * from book_list;"
  cur.execute (sql)
  rows=cur.fetchall ()
  for row in rows:
    book_bar.append (row [1])
  book_list=[] #This is used when I test,The role is to put a list of information about each book in this list
  book_every=[] #list of all information for a book
  for book_time in soup.find_all ("td", class _="whitetext"):
    print (book_time.get_text (). strip ()) #remove specified characters from the beginning and end of the string
    pattern=re.compile (r "\ s")
    content=re.sub (pattern, r "", book_time.get_text ()) #The purpose is also to match and remove any whitespace,Seems to have no effect on blank line removal
    if content!="":
      book_every.append (content)
      if len (book_every) == 7:
        book_list.append (book_every)
        if book_every [0] not in book_bar:
          sql="insert book_list (barcode, title and author, Borrowing date, Due date, Renewal amount, collection place, attachment) value ("+" \ "" \
             + book_every [0] + "\", "+" \ "" + book_every [1] + "\", "+" \ "" + book_every [2] + "\", "+" \ "" \
             + book_every [3] + "\", "+" \ "" + book_every [4] + "\", "+" \ "" + book_every [5] + "\", "+" \ "" \
             + book_every [6] + "\" "+");"
        try:
          cur.execute (sql)
          conn.commit ()
        except:
          conn.rollback ()
        book_every=[]
  print (book_list)

Next we analyze the uncommented code in the above code.First we add the processed information tobook_every list, and then from the page source code (tp9.png), we can know thatOnly the first 7 items are needed in a book's information, so we use a judgment statement:

if len (book_every) == 7:
  book_list.append (book_every)
  if book_every [0] not in book_title:
    sql="insert book_list (barcode, title and author, Borrowing date, Due date, Renewal amount, collection place, attachment) value ("+" \ "" \
             + book_every [0] + "\", "+" \ "" + book_every [1] + "\", "+" \ "" + book_every [2] + "\", "+" \ "" \
             + book_every [3] + "\", "+" \ "" + book_every [4] + "\", "+" \ "" + book_every [5] + "\", "+" \ "" \
             + book_every [6] + "\" "+");"
    try:
      cur.execute (sql)
      conn.commit ()
    except:
      conn.rollback () #If saving to the database fails,Perform a rollback operation
  book_every=[]

That is,If you determinebook_every has reached 7 items, then the operation of storing into the database is performed,Then putbook_every Reset to empty list

Third, send email reminder function

Paste the code first:

def send_message ():
  day_num=[31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
  day_num1=[31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
  sql="select * from book_list;"
  cur, conn=get_mysql ()
  cur.execute (sql)
  rows=cur.fetchall ()
  local_time=time.strftime ("%y-%m-%d", time.localtime ()) #Get the current time
  local_time=str (local_time)
  times=re.split (r "-", local_time)
  year=times [0]
  number=0
  while (true):
    for i in rows:
      print (i [4])
      pattern=re.split (r "-", i [4])
      if times [1] == pattern [1]:
        day=int (times [2])-int (pattern [2])
        if day>0:
          print ("Expired%d days"%day)
          number +=1
          send_email (day, number, i [2])
      elif times [1]>pattern [1]:
        if (year%4 == 0 and year%100!=0) or year%400 == 0:
          extend_day=day_num1 [int (pattern [1])-1]-int (pattern [2]) + times [2]
          print ("Expired%d days"%extend_day)
          number +=1
          send_email (day, number, i [2])
        else:
          extend_day=day_num [int (pattern [1])-1]-int (pattern [2]) + times [2]
          print ("Expired%d days"%extend_day)
          number +=1
          send_email (day, number, i [2])
      else:
        print ("No expired books")
      print (pattern [2])
    time.sleep (3600 * 24)

Let's analyze the code,First, we judge whether the overdue is obtained by adding and subtracting the current time and the due date.So we consider:

1. If the due date is last month,Here we are going to add and subtract months.Because the leap year and month are different,So we define day_num and day_num1 lists to represent the number of days in the leap year and the year of the month.

2. Then we use the month as the judgment condition to compare the number of overdue days

Month judgment,If the current month is equal to the due month,Do the following,Note that it already contains the send mail function,The send mail function will be posted below,Everyone may think,Why did n’t you judge the year,Because I usually do n’t expire books so long,So this judgment is not added

     if times [1] == pattern [1]:
        day=int (times [2])-int (pattern [2])
        if day>0:
          print ("Expired%d days"%day)
          number +=1
          send_email (day, number, i [2])

Then when the current month is greater than the due month,At this time, the judgment of the leap year and the peace year is up.

     elif times [1]>pattern [1]:
        if (year%4 == 0 and year%100!=0) or year%400 == 0:
          extend_day=day_num1 [int (pattern [1])-1]-int (pattern [2]) + times [2]
          print ("Expired%d days"%extend_day)
          number +=1
          send_email (day, number, i [2])

Below is the code to send the email:

def send_email (day, number, title):
  from_addr="[email protected]"
  password="I won't tell you"
  to_addr="[email protected]"
  smtp_server="smtp.163.com"
  text="hello, Guo Weikuang, tell you a bad news,Hurry up with your book,Go to the library and pay! You have a book called "%s" that has expired "\
      ", And it has expired%d days, and a total of%d books have expired !!!"%(title, day, number)
  msg=mimetext (text, "plain", "utf-8")
  msg ["from"]=format_addr ("Library notifications<%s>"%from_addr)
  msg ["to"]=format_addr ("admin<%s>"%to_addr)
  msg ["subject"]=header ("A greeting from Guo Weikuang.
..... "," utf-8 "). encode ()
  server=smtplib.smtp (smtp_server, 25)
  server.set_debuglevel (1)
  server.login (from_addr, password)
  server.sendmail (from_addr, [to_addr], msg.as_string ())
  server.quit ()

Finally send out a screenshot of the sent email:

  • Previous Fully understand the role of Native keywords in Java
  • Next Cartclassphp definition and usage example