Python practice: one click export of wechat books and notes

Keywords: Programming Excel Qt JSON Python

The era of reading for all has come. At present, there are 210 million users who use reading software and more than 5 million daily active users. Among them, more than 60% are 19-35-year-old young users, 80% are undergraduates or above, and more than 80% are beishangguangshen and other provincial capitals / municipalities directly under the central government.

I used to use wechat to read books. In order to organize books and export notes conveniently, I developed this little tool

Partial screenshots

Code thinking

1. Directory structure

First, let's take a look at the overall directory structure

Code
├─ excel_func.py                   Read and write excel file
├─ pyqt_gui.py                     PyQt GUI Interface
└─ wereader.py                     Wechat reading related api

Using xlrd and xlwt libraries to read and write excel files

PyQt gui.py use PyQt to draw GUI interface

wereader.py obtains relevant api through packet capturing and parsing

2,excel_func.py

def write_excel_xls(path, sheet_name_list, value):
    # Create a new workbook
    workbook = xlwt.Workbook()
​
    # Get the number of rows to write data to
    index = len(value)
​
    for sheet_name in sheet_name_list:
​
        # Create a new table in the workbook
        sheet = workbook.add_sheet(sheet_name)
​
        # Write data to the table in this workbook
        for i in range(0, index):
            for j in range(0, len(value[i])):
                sheet.write(i, j, value[i][j])
​
    # Save Workbook
    workbook.save(path)

The code flow of this function is:

Create excel file

Create table

Write data to table

3,pyqt_gui.py

class MainWindow(QMainWindow):
​
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
​
        self.DomainCookies = {}
​
        self.setWindowTitle('Wechat reading assistant') # Set window title
        self.resize(900, 600) # Set window size
        self.setWindowFlags(Qt.WindowMinimizeButtonHint) # Disable maximize button
        self.setFixedSize(self.width(), self.height()) # Disable window resizing
​
        url = 'https://Weread. QQ. COM / ා Login 'ා destination address
        self.browser = QWebEngineView() # Instancing browser objects
​
        QWebEngineProfile.defaultProfile().cookieStore().deleteAllCookies() # Delete all cookies when running the software for the first time
​
        QWebEngineProfile.defaultProfile().cookieStore().cookieAdded.connect(self.onCookieAdd) # Trigger self.onCookieAdd() function when cookies are added
        self.browser.loadFinished.connect(self.onLoadFinished) # Trigger the self.onLoadFinished() function when the web page is loaded
​
        self.browser.load(QUrl(url)) # Loading webpage
        self.setCentralWidget(self.browser) # Set center window

The code flow of this function is:

New QT window

Instantiate QWebEngineView object

Bind self.onCookieAdd event

Bind the self.onLoadFinished event

Loading webpage

    # Page load complete event
    def onLoadFinished(self):
​
        global USER_VID
        global HEADERS
​
        # Get cookies
        cookies = ['{}={};'.format(key, value) for key,value in self.DomainCookies.items()]
        cookies = ' '.join(cookies)
        # Add Cookie to header
        HEADERS.update(Cookie=cookies)
​
        # Judge whether you successfully log in to wechat reading
        if login_success(HEADERS):
            print('Success in wechat reading!')
​
            # Get user? Vid
            if 'wr_vid' in self.DomainCookies.keys():
                USER_VID = self.DomainCookies['wr_vid']
                print('user id:{}'.format(USER_VID))
​
                # Close the entire qt window
                self.close()
​
        else:
            print('Please scan QR code to log in to wechat...')

The code flow of this function is:

When the web page is loaded, check whether it is successfully logged in to wechat for reading

If you log in to wechat successfully, close the QT window and start data export

If you fail to log in to wechat to read, continue to wait for the user to scan the QR code

    # Add cookies event
    def onCookieAdd(self, cookie):
        if 'weread.qq.com' in cookie.domain():
            name = cookie.name().data().decode('utf-8')
            value = cookie.value().data().decode('utf-8')
            if name not in self.DomainCookies:
                self.DomainCookies.update({name: value})

The code flow of this function is:

Save cookies of wechat reading website for subsequent operation

    books = get_bookshelf(USER_VID, HEADERS) # Get books on the shelf
    books_finish_read = books['finishReadBooks']
    books_recent_read = books['recentBooks']
    books_all = books['allBooks']
    write_excel_xls_append(data_dir + 'my bookshelf.xls', 'Finished books', books_finish_read) # Add write excel file
    write_excel_xls_append(data_dir + 'my bookshelf.xls', 'Recent books', books_recent_read)  # Add write excel file
    write_excel_xls_append(data_dir + 'my bookshelf.xls', 'All the books', books_all)  # Add write excel file
​
    # Get notes for each book on the shelf
    for index, book in enumerate(books_finish_read):
        book_id = book[0]
        book_name = book[1]
        notes = get_bookmarklist(book[0], HEADERS)
​
        with open(note_dir + book_name + '.txt', 'w') as f:
            f.write(notes)
        print('Export notes {} ({}/{})'.format(note_dir + book_name + '.txt', index+1, len(books_finish_read)))

The code flow of this function is:

Call the write excel XLS append function to save the book and export the notes.

4,wereader.py

def get_bookshelf(userVid, headers):
    """Get all the books on the shelf"""
    url = "https://i.weread.qq.com/shelf/friendCommon"
    params = dict(userVid=userVid)
    r = requests.get(url, params=params, headers=headers, verify=False)
    if r.ok:
        data = r.json()
    else:
        raise Exception(r.text)
​
    books_finish_read = set() # Finished books
    books_recent_read = set() # Recent books
    books_all = set() # All the books on the shelf
​
​
    for book in data['recentBooks']:
        if not book['bookId'].isdigit(): # Filtering official account
            continue
        b = Book(book['bookId'], book['title'], book['author'], book['cover'], book['intro'], book['category'])
        books_recent_read.add(b)
​
    books_all = books_finish_read + books_recent_read
​
    return dict(finishReadBooks=books_finish_read, recentBooks=books_recent_read, allBooks=books_all)

The code flow of this function is:

Get the latest books, the finished books, all the books

Filtering official account

Save book data in dictionary format

def get_bookmarklist(bookId, headers):
    """Get notes of a Book Return md text"""
    url = "https://i.weread.qq.com/book/bookmarklist"
    params = dict(bookId=bookId)
    r = requests.get(url, params=params, headers=headers, verify=False)
​
    if r.ok:
        data = r.json()
        # clipboard.copy(json.dumps(data, indent=4, sort_keys=True))
    else:
        raise Exception(r.text)
    chapters = {c['chapterUid']: c['title'] for c in data['chapters']}
    contents = defaultdict(list)
​
    for item in sorted(data['updated'], key=lambda x: x['chapterUid']):
        # for item in data['updated']:
        chapter = item['chapterUid']
        text = item['markText']
        create_time = item["createTime"]
        start = int(item['range'].split('-')[0])
        contents[chapter].append((start, text))
​
    chapters_map = {title: level for level, title in get_chapters(int(bookId), headers)}
    res = ''
    for c in sorted(chapters.keys()):
        title = chapters[c]
        res += '#' * chapters_map[title] + ' ' + title + '\n'
        for start, text in sorted(contents[c], key=lambda e: e[0]):
            res += '> ' + text.strip() + '\n\n'
        res += '\n'
​
    return res

The code flow of this function is:

Take notes of a Book

Rewrite the returned string to markdown format and output

How to run

# Jump to current directory
cd Directory name
# Uninstall dependency library first
pip uninstall -y -r requirement.txt
# Reinstall the dependent Library
pip install -r requirement.txt -i https://pypi.tuna.tsinghua.edu.cn/simple
# Start running
python pyqt_gui.py

Original link: https://www.cnblogs.com/cloudbird/p/12683546.html Source network, only for learning, if there is infringement, contact delete.

I have collected high-quality technical articles and experience summary in my official account [Python circles].

Don't panic. I have a set of learning materials, including 40 + E-books, 600 + teaching videos, involving Python foundation, reptile, framework, data analysis, machine learning, etc. I'm not afraid you won't learn!

file

Posted by AcidRain on Thu, 16 Apr 2020 01:21:39 -0700