2011.6.18头条搜索页面进行更新后,不可以通过http直接获取源代码了,必须使用selenium来获取。以下代码部分已经不能使用,html = httprequest(url)
最近想学习python玩玩,python可以做的事太多,web,大数据,人工智能等等,web已经掌握了node和.net,没必要再去学web了,就搞个爬虫玩玩吧。
为什么选择今日头条呢?
一,因为今日头条robots文件,对百度做了限制,所以百度是无法搜到今日头条的文章的,所以对于百度来说,我爬来的每一篇文章,可能百度都会认为我是原创的。
二,作为一个很火的自媒体平台,每天都有几百万的更新量,资源丰富,源源不断。
b站上看了几段python视频后,就开始写代码啦。
主要就是这几个文件,demo忽略,geckodriver.log是selenium自动生成的日志文件,httprequest是再做一次requests封装,spiler是主程序,toutiao就是针对今日头条的爬虫,以后或许会增加不同网站的爬虫那就再增加相应的模块即可。
首先安装基本必要的模块
pip install fake_useragent
pip install bs4
pip install requests
httprequest文件,fake_useragent随机生成User-Agent,用来隐藏爬虫身份,再设置一下代理IP,就避免有些服务器针对你频繁的访问而限制你的IP,下面的IP不可用哦,仅仅是示例,网上有很多出售代理IP的商家,也不贵,当然如果你觉得不需要,那就不要设置代理IP。
import requests
from fake_useragent import UserAgent
def httprequest(url):
proxyHost = "60.172.83.116" # 示例IP不可用
proxyPort = "4231" # 端口
proxyMeta = "http://%(host)s:%(port)s" % {
"host": proxyHost,
"port": proxyPort
}
proxies = {
"http": proxyMeta,
"https": proxyMeta
}
ua = UserAgent()
headers = {
"User-Agent": ua.random,
"Accept-Language": "zh - CN, zh",
"Cache-Control": "no - cache",
"Connection": "keep - alive"
}
# 由于使用代理IP,会比较慢,所以timeout尽量设置长一点。
result = requests.request("get",url, headers=headers,proxies=proxies,timeout=8)
return result.text
spider文件没啥多说的,以后如果有针对不同的爬虫,会在main函数下补充
from toutiao import toutiao
def main():
toutiao()
if __name__ == "__main__": # 只有当运行此模块时才会执行,被引入模块时,不会执行
main()
toutiao文件,才是重点,先研究一下头条的搜索页面,可以看到url的组成部分,最重要的参数就是keyword和page_num了,经过测试dvpf=pc参数也是必须的,知道规律后就可以写代码了。
通过chrome分析,可以找到每一条链接的关键字如下,经过测试,通过div.text-xl>a.text-ellipsis选择器就能获得所有链接了。不得不提一下python爬虫为什么那么强大,与BeautifulSoup不无关系,此模块实在是强大,如同使用jquery选择一样,就能非常方便的定位到自己所要的元素。
好了,思路明确,开始写代码,先导入必要的模块。
from httprequest import httprequest
from bs4 import BeautifulSoup
import time
import re
from urllib import parse
由控制台输入要搜索的关键字,以及从第几页开始抓取,这样以后要搜索不同的关键字,就不用来改源码了。
def toutiao():
keyword = input("请输入关键字")
host = "https://so.toutiao.com"
urllist = [] # 所有文章url列表
urllist2 = [] # 过滤后最终简洁的url列表
link=re.compile(r"url=(.*?)/\?")
try:
pagenum = int(input("起始页码"))
limtpage = int(input("检索多少页"))
except:
print("输入的不是整数")
for index in range(limtpage):
url = "%s/search?keyword=%s&dvpf=pc&page_num=%d"%(host,
keyword, pagenum)
print("提取[%s]关键字列表,当前第%d页,还剩%d页"%
(keyword, pagenum, limtpage-index-1))
html = httprequest(url)
soup = BeautifulSoup(html, 'html.parser')
list = soup.select("div.text-xl>a.text-ellipsis")
for item in list:
urllist.append(parse.unquote('%s%s' % (host, item["href"])))
time.sleep(1)
pagenum = pagenum+1
至此,所有链接已经保存到urllist这个数组里,可以看到,真正的链接是参数url后面的地址,我们只需要 https://www.toutiao.com/**** 这串地址就行
接下来再循环一下数组,用正则匹配出最终简洁的链接。
for item in urllist:
if(len(re.findall(link, item))>0):
urllist2.append(re.findall(link,item))
# 读取正文内容
for item in urllist2:
print(item[0])
# 这里开始再爬取正文的内容
time.sleep(1)
现在再看看效果,是不是简洁了许多?
好了,列表已经爬到,接下来就是爬取正文了。
今日头条的正文部分,进行了非常复杂的cookie输出,再加密的过程,需要使用到selenium模块,具体过程下一篇再写。