Python+Selenium模拟按键抓取今日头条

问题描述

爬取今日头条作者的全部文章,这里以我室友的头条号(紫醉金迷)为例。今日头条作者页面的文章列表是js加载的,但具体的文章内容是HTML。判断用Chrome浏览器,设置里面禁用JavaScript,重新加载,如果页面只加载部分,则未加载部分采用Ajax加载。

解决

本篇文章采用Selenium模拟浏览器,BeautifulSoup内容抓取,具体内容文章可以用Requests库,但这里只爬一个人的,就不考虑效率问题了,都用Selenium。

爬取作者的全部文章链接

先配置好Selenium后,打开作者的url,要获取Ajax内容,这里有两个思路。

  1. 模拟浏览器不停的下拉,driver.execute_script('window.scrollTo(0, document.body.scrollHeight)'),但这种方法经常加载不了,而且driver.page_source的内容不变
  2. 模拟按键DOWN,不停的加载,直到全部加载完,保存page_source,简单粗暴。
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    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中的网址,一个一个打开,获取内容。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
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

----------本文完,感谢您的阅读----------