惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

S
SegmentFault 最新的问题
The Last Watchdog
The Last Watchdog
P
Proofpoint News Feed
C
Cybersecurity and Infrastructure Security Agency CISA
L
LINUX DO - 热门话题
Cyberwarzone
Cyberwarzone
S
Schneier on Security
C
CERT Recently Published Vulnerability Notes
Latest news
Latest news
I
Intezer
A
Arctic Wolf
IT之家
IT之家
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
C
Cisco Blogs
AWS News Blog
AWS News Blog
博客园 - 三生石上(FineUI控件)
C
CXSECURITY Database RSS Feed - CXSecurity.com
F
Fortinet All Blogs
Microsoft Azure Blog
Microsoft Azure Blog
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
T
The Exploit Database - CXSecurity.com
Google DeepMind News
Google DeepMind News
M
MIT News - Artificial intelligence
D
Docker
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
C
Cyber Attacks, Cyber Crime and Cyber Security
MongoDB | Blog
MongoDB | Blog
B
Blog
博客园 - 叶小钗
V2EX - 技术
V2EX - 技术
Simon Willison's Weblog
Simon Willison's Weblog
MyScale Blog
MyScale Blog
Hugging Face - Blog
Hugging Face - Blog
Engineering at Meta
Engineering at Meta
NISL@THU
NISL@THU
WordPress大学
WordPress大学
人人都是产品经理
人人都是产品经理
Stack Overflow Blog
Stack Overflow Blog
N
Netflix TechBlog - Medium
The GitHub Blog
The GitHub Blog
V
V2EX
PCI Perspectives
PCI Perspectives
N
News | PayPal Newsroom
V
Visual Studio Blog
Vercel News
Vercel News
P
Proofpoint News Feed
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
J
Java Code Geeks
O
OpenAI News
爱范儿
爱范儿

博客园 - pmh905001

爬虫-今日头条我的收藏-反爬虫分析(六) pycharm的没落,vs code的兴起 爬虫-今日头条我的收藏-增量式下载网页内容(五) 爬虫-今日头条我的收藏-增量式导入到Elastic Search(四) 今日头条源代块一行代码很长情况下的拖动问题 爬虫-今日头条我的收藏-增量式导入到mongodb(三) openpyxl一个bug 爬虫-今日头条我的收藏(一) pystray被隐藏菜单项显示出来的问题 pyinstaller生成的exe程序使用使用默认程序打开execel文件 pyinstaller生成的exe文件的所在的工作目录问题 windows下python的keyboard库在锁屏之后再次登陆快捷键(热键)失效问题 pyinstaller 报错ImportError: No module named _bootlocale windows下gitbash 鼠标左键选中文字自动自行终止命令 ctrl+c ^C spring-security 如何使用用户名或邮箱登录 tomcat jndi context.xml的特殊字符转义问题 struts2的优缺点以及如何改造 jetty-maven-plugin 版本导致jetty启动失败问题 Eclipse下pom.xml的提示 Cannot access defaults field of Properties
爬虫-今日头条我的收藏-增量式(二)
pmh905001 · 2023-12-19 · via 博客园 - pmh905001

背景:

能够全量爬取今日头条我的收藏内容之后,新收藏的内容依然希望能够保存到新文件中。

思路:

  • 每次都全量爬取数据太耗时,增量式爬取可以节省时间。但逻辑上显然要复杂一些。关键的问题是要找到断点的位置。
  • 取消收藏的影响:爬虫旧文件用户收藏的链接有可能被取消收藏。所以在断点位置的判断上不能只取一条数据的id作为参考,考虑取连续100条的我的收藏id作为判断基准,这样即便用户偶尔取消收藏几条,依然能够准确找到断点。
  • 增量式功能可以覆盖全量下载我的收藏。第一次下载由于没有断点,需要全量下载。后续由于已经有下载的文件作为参照物,只需要从参照物继续下载。
  • 每次运行增量爬虫,如果有新内容,则新增一个文件,文件格式:myfavorites-年月日-时分秒.txt。如果没有新内容,不需要新增文件。

实现:

  • 代码参考这里:https://github.com/pmh905001/myfavorite/blob/master/toutiao/increasmentdownload.py .主代码如下:
    def increasement_download():
        url, headers = read_curl()
        latest_ids_downloaded = latest_ids_from_file()
        page = get_page(url, headers, 0, latest_ids_downloaded)
        try_num = 0
        file_name = f'myfavorites-{time.strftime("%Y%m%d-%H%M%S")}.txt'
        while page['has_more']:
            try_num += 1
            max_behot_time = page['next']['max_behot_time']
            write_page(page, file_name)
            sleep_time = random.randint(1, 10)
            print(f'-------------------------------------------page number: {try_num}, sleep {sleep_time} seconds')
            time.sleep(sleep_time)
            page = get_page(url, headers, max_behot_time, latest_ids_downloaded)
        else:
            write_page(page, file_name)
  • 从断点处按照有新到旧的id需要获取最多100条,这种情况下需要遍历所有myfavorites-年月日-时分秒.txt的文件且需要倒序排列,依次读取id直到100条(用户可以自己调整)。参考latest_ids_from_file()
    def latest_ids_from_file():
        ids = []
        my_favorite_files = sorted([f for f in os.listdir('.') if f.startswith('myfavorites-')], reverse=True)
        for file_name in my_favorite_files:
            with open(file_name, 'r', encoding='utf-8') as f:
                page: dict = json.loads(f.readline())
                if page.get('data'):
                    for record in page['data']:
                        if len(ids) <= 100:
                            ids.append(record['id'])
                        else:
                            return ids
        return ids
  •  在获取每页的数据之后,需要找到断点,把冗余的数据给删除。重置has_more=False。参考get_page()方法
    def get_page(url, headers, max_behot_time=0, latest_ids_downloaded=[]):
        url = replace_url_param(url, 'max_behot_time', max_behot_time)
        response = requests.get(url, headers=headers)
        page: dict = response.json()
        if page.get('data'):
            for index, record in enumerate(page.get('data')):
                if record['id'] in latest_ids_downloaded:
                    page['data'] = page['data'][:index]
                    page['has_more'] = False
  •  在写文件的时候,如果页数据收藏列表如果为空,则不写入文件。参考write_page()
    def write_page(page, file_name):
        if not page.get('data'):
            return
        with open(file_name, 'a', encoding='utf-8') as fp:
            page_info = json.dumps(page, ensure_ascii=False)
            fp.write(page_info)
            fp.write('\n')
    
        for item in page['data']:
            try:
                print(f"{item['id']}: {item['title']}   => {item['share_url']}")
            # Fixme: UnicodeEncodeError
            except UnicodeEncodeError:
                logging.exception('occurred exception when print')
  • 代码写的比较粗糙,还需要找时间重构。这里仅供参考