问题描述
爬取今日头条作者的全部文章,这里以我室友的头条号(紫醉金迷)为例。今日头条作者页面的文章列表是js加载的,但具体的文章内容是HTML。判断用Chrome浏览器,设置里面禁用JavaScript,重新加载,如果页面只加载部分,则未加载部分采用Ajax加载。
解决
本篇文章采用Selenium模拟浏览器,BeautifulSoup内容抓取,具体内容文章可以用Requests库,但这里只爬一个人的,就不考虑效率问题了,都用Selenium。
爬取作者的全部文章链接
先配置好Selenium后,打开作者的url,要获取Ajax内容,这里有两个思路。
- 模拟浏览器不停的下拉,
driver.execute_script('window.scrollTo(0, document.body.scrollHeight)')
,但这种方法经常加载不了,而且driver.page_source
的内容不变 模拟按键
DOWN
,不停的加载,直到全部加载完,保存page_source
,简单粗暴。def get_urls(url): driver.get(url) #打开网址 time.sleep(1) driver.refresh() #这里要刷新一下,不然第一次加载没反应 driver.implicitly_wait(2) #隐性等待2秒 for i in range(10000): #这里循环次数尽量大,保证加载到底 ActionChains(driver).key_down(Keys.DOWN).perform() #相当于一直按着DOWN键 print(f'已完成{i}次') time.sleep(3) soup = BeautifulSoup(driver.page_source, 'html.parser') body = soup.find_all(class_='link title') #提取网址 for i in range(len(body)): url = 'https://www.toutiao.com' + body[i].get('href') print(f'已完成{i}个') with open('urls.txt', 'a') as f: #把网址按行保存到urls.txt f.writelines(url) f.write('\n') driver.quit()
爬取文章的标题,作者,发布时间,正文
这个就很简单了,把urls.txt中的网址,一个一个打开,获取内容。
def get_htmls(): with open('urls.txt', 'r') as f: urls = f.readlines() l = len(urls) htmls = [] for i in range(l): print(urls[i]) driver.get(urls[i]) driver.execute_script('window.scrollTo(0, document.body.scrollHeight)') #加载到底部,保证图片文章中的图片加载完 soup = BeautifulSoup(driver.page_source, 'html.parser') try: #如果异常,刷新一下 body = str(soup.find_all(class_='article-title')[0]) + str(soup.find_all( class_='article-sub')[0]) + str(soup.find_all(class_='article-content')[0]) #获取标题,时间,正文 except IndexError: driver.refresh() time.sleep(2) if not os.path.exists('htmls'): os.mkdir('htmls') with open(f'htmls/{i}.html', 'w') as f: #保存到htmls文件夹下 f.write(body) print(f'{i}.html 完成, 共{l}个') time.sleep(3) driver.quit()
把html转换为markdown或pdf格式
完整代码详见 https://github.com/itswcg/crawler-toutiao, 欢迎点赞。