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!