写在前面:
就在昨天,豆酱的某乎在第二次15天禁言之后,又被有计划的禁言了15天,亦便是说截止昨天(2020/3/27),豆酱由于之前的评论已然被禁言过7+15天,并将再加将来15天。可见这个并不是一时冲动的行径,而是有计划的。首要我相信某乎的公正性,亦感谢做这个事情的人没对我的号做什么。 然则做为对豆酱昨天被禁言的回复,今天我的文案会调节一下。原计划是给大众科普自然语言处理(NLP)和文本归类,但今天我会先放出我B站视频展示的约600篇文案是怎样爬取的技术文。
最后我想对哪些不爱好我的人说:我是个技术人,我起始尝试做内容是期盼让大众展示好玩的技术,吸引大众学习知识。虽然我写的文案和视频导致了争议,然则我始终期盼跟大众讲解的怎样得到和爬取数据,怎样分析,我的结论是怎样得到的,期盼大众爱好这般探讨问题的办法。我虽然有自己的观点,我夫人亦爱好肖战,但咱们并不想针对或死磕任何人。 你们正在运用你们所不齿的办法针对咱们。 古话有云:己所不欲勿施于人。
文案无图有料,不懂技术的各位亦应该仔细瞧瞧。
在之前的文案中,我已然和大众分享了怎样直接爬取AO3的文案,那样怎样找到文案的相关关系是一件比较头疼的问题。倘若自己去写爬虫会比较浪费资源。最省事的办法便是借助搜索引擎进行资料获取。这儿,咱们就以 lofter 到 AO3 的外链为例。
加载的函数库还是与之前相同,这儿我再也不复述。 import sys
import re
import os
import time
from tqdm import tqdm
from selenium import webdriver
from selenium.common.exceptions importNoSuchElementException
from bs4import BeautifulSoup
import random这儿和大众科普一下搜索引擎的高级搜索模式,平时大众运用搜索引擎,可能都是一整句话放进去搜索。但实质上搜索引擎是支持必定的高级语法以方便获取到更高级的内容。咱们以谷歌为例:
“”精确匹配
运用引号来搜索一个完全匹配的字词或一组字词。在搜索歌词或文学作品中的一段文字时,此选项很实用。意见您仅在查询非常确切的字词或词组时运用该功能,否则可能会无意中排除掉有用的搜索结果。
例如“见与不见” 搜索结果精确匹配“见与不见”,不可拆分成“见”与“不见”。
-排除字词
在某个字词前添加短横 (-) 可排除所有包括该字词的搜索结果。
例如:大熊猫 -百科 搜索结果中不显现“百科”
OR选取性字词搜索
选取性字词OR搜索结果匹配多个搜索字词中的任意一个。无OR搜索结果中一般只会表示与多个字词都匹配的网页。
例如:奥运会 2014 OR 2018 搜索结果中会显现 “奥运会 2014”或“奥运会 2018”的结果
site在特定网站或域名中搜索
在搜索中加入“site:”能够限定在某个特定网站中搜索信息
例如:LOFTER site:lofter.com
“site:”后面跟的站点域名,不要带“http://”。site:和站点名之间,不要带空格。
inurl在特定url链接中搜索
在搜索中加入“inurl:”能够限定在网站url链接中搜索网站信息
例如:auto视频教程 inurl:video
搜索词“auto视频教程”是能够出此刻网页的任何位置,而“video”则必须出此刻网页url中。
以上只是谷歌的部分高级搜索语法,百度亦有类似的运用办法,大众能够自己去查查仔细的运用办法。咱们这儿用到了 site: 标签 和 inurl: 标签 亦便是:
site:lofter.com inurl:ao3
这条语句的含义是,在 lofter.com 中 搜索 含有 ao3 链接 的结果。这儿需要重视,实质搜索过程中,"ao3" 需要换成该网站的实质域名。这儿由于不想透露真实网站位置因此运用了 "ao3" 替代。
分析url 的思路我在 《我是怎么样得到AO3内容的》 有介绍过,这儿直接给结论。谷歌的url 由 search?后的内容形成: hl=en 暗示搜索语言为英文 q= 后跟搜索内容 safe= 跟的是是不是为安全搜索,这儿运用images参数关闭安全搜索亦便是能够搜索到欠好的信息~ num= 暗示每页展示的搜索条数start= 暗示从第几条起始表示,所以翻页的计算办法为 start = page*num这儿说明一下,我确实专门搜索了语言为英文的页面,但搜索引擎的模糊性使得结果依然有大部分是中文文案。然则我能够证明两点: 之前有说在ao3 看英文或学英语是真实的;我还无起始做文本分析,但就我看过的几篇英文文案中,以我留过学的经历来衡量,文案中确实含有书本上通常学不到的东西和词汇;【手动狗头】言归正传看代码: #获谷歌取搜索页面
def make_google_search_url(page=0, num=100):
base_loc = https://www.google.com/search?hl=en&q=site:lofter.com+inurl:ao3&safe=images
base_loc += "&num="+str(num)
base_loc += "&start="+str(page*num) #搜索页
return base_loc获取链接的办法依然是 chrome 浏览器调试模式(F12)分析元素并用 BeautifulSoup 解析,这儿再也不复述,大众直接看代码。 #从谷歌获取文案链接
def get_url_from_search(html):
old_list = []
soup = BeautifulSoup(html, html.parser)
search_div = soup.find(div, attrs={id: search})
div_g_groups = search_div.findAll(div, attrs={class: g})
for g in div_g_groups:
div_r = g.find(div, attrs={class: r})
a_hurl = div_r.find(a)
old_list.append(a_hurl[href])
return old_list最后便是判断 lofter 的页面中是不是含有 有效的 ao3 链接。根据之前的经验,判定含有 works 的 url 才思虑为有外链文案。然则在后来实践过程中 发掘含有 users 的外链亦非常有意思,就一并保留了。
保留的内容有: lofter 页面,本 lofter 页面中所有含有 ao3 外链的链接,所有触及的 ao3 原文页面,ao3 用户介绍页(内含该用户所有文案)
重视,日前日前我只是保留了 ao3 用户介绍页(倘若有)。并无进行二次爬取或分析。
另一相比 《我是怎样得到AO3内容的》中的函数,这儿进行了优化,当显现“Retry later”时,函数会自动重试,而不会想之前就直接把这一页放过不保留了。
代码中 ao3 站点位置我运用 xxx 代替。 def find_ao3_from_lofter(lofter_url_list, browser, path):
for url in lofter_url_list:
print(url)
dir_name = (
url.replace("http://", "")
.replace(".com/", "_")
.replace("/", "_")
.replace(".", "_")
)
dir_path =os.path.join(path, dir_name)
isExists = os.path.exists(dir_path)
if isExists:
print("Exists")
continue
# 判断结果
ao3_links = []
browser.get(url)
currurl = browser.current_urlif "xxx" in currurl and (
"/works/" in currurl or "/users/" incurrurl
): # 倘若url 直接转
ao3_links.append(currurl)
lhtml =""
else: # 无转
lhtml = browser.page_source
soup = BeautifulSoup(lhtml, "html.parser")
alink_groups = soup.findAll("a", attrs={"rel": "nofollow"})
for alink in alink_groups:
href_str = alink["href"]
if "xxx" in href_str and (
"/works/" in href_str or "/users/" inhref_str
):
ao3_links.append(href_str)if ao3_links:
# 判断路径是不是存在
isExists = os.path.exists(dir_path)
# 倘若不存在则创建目录
os.makedirs(dir_path)
links_str = url +"\n"
need_agree = True
for work_url in ao3_links: # 遍历ao3链接
links_str += work_url + "\n"
print(os.path.join(dir_path, "links.txt"))
fh =open(os.path.join(dir_path, "links.txt"), "w") # 保留页面
fh.write(links_str) # 写入内容
fh.close() # 关闭
print(os.path.join(dir_path, "lofter.html"))
fh =open(os.path.join(dir_path, "lofter.html"), "w") # 保留页面
fh.write(lhtml) # 写入内容
fh.close() # 关闭
for work_url inao3_links:
browser.get(work_url)if need_agree:
try:
time.sleep(3)
browser.find_element_by_id("tos_agree").click()
time.sleep(1)
browser.find_element_by_id("accept_tos").click()time.sleep(1)
need_agree = False
except NoSuchElementException:
need_agree = False
work_html_text = browser.page_source # 得到页面代码
work_name = (
work_url.replace("https://", "")
.replace("http://", "")
.replace("xxx", "")
.replace(".com/", "")
.replace(".org/", "")
.replace("/", "_")
.replace(".", "_")
.replace("#", "_")
)
work_path = os.path.join(dir_path, work_name + ".html")
if (
If you accept cookies from our site and you choose "Proceed"
in work_html_text
): # 没法获取正文则点击Proceed
browser.find_element_by_link_text("Proceed").click()time.sleep(1)
browser.get(work_url)
work_html_text = browser.page_source
if "Retry later" in work_html_text:
while "Retry later" in work_html_text:
print(work_path)
fh = open(work_path, "w") # 保留页面
fh.write("Need_to_reload") # 写入内容
fh.close() # 关闭
print("Retry Later")
time.sleep(3)
browser.get("http://www.baidu.com")
time.sleep(3)
browser.quit()
c_service.stop()
time.sleep(60)
c_service.start()
browser = webdriver.Chrome(
chrome_options=chrome_options
) # 调用Chrome浏览器
browser.get("https://xxx.org/")
time.sleep(5)
browser.find_element_by_id("tos_agree").click()time.sleep(2)
browser.find_element_by_id("accept_tos").click()
time.sleep(3)
browser.get(work_url)
work_html_text = browser.page_source # 得到页面代码if (
If you accept cookies from our site and you choose "Proceed"
inwork_html_text
): # 没法获取正文则点击Proceed
browser.find_element_by_link_text("Proceed").click()
time.sleep(1)
browser.get(work_url)
work_html_text = browser.page_source
# if "<!--chapter content-->" inwork_html_text:print(work_path)
fh = open(work_path, "w") # 保留页面
fh.write(work_html_text) # 写入内容
fh.close() # 关闭
time.sleep(float(random.randint(10, 50)) /10) # 随机延时
return browser设置起止页 start_p = 0
end_p = 4
倘若平凡运用谷歌,谷歌会起步防设备人机制,这是函数会暂停等待我人工解锁的。
因此这儿我亦相当于解释了我为何无翻墙,由于倘若我运用翻墙软件爬取,是会被谷歌发掘并封杀掉的,而怎样绕过呢?卖个关子,瞧瞧有无懂行的伴侣帮大众解释一下。 c_service = webdriver.chrome.service.Service("/usr/bin/chromedriver")
c_service.command_line_args()
c_service.start()
chrome_options = webdriver.ChromeOptions()# chrome_options.add_argument(--proxy-server=socks5://localhost:1080)auto_quit_cnt = 0
browser = webdriver.Chrome(chrome_options=chrome_options)# 调用Chrome浏览器
for page in range(start_p, end_p):
print("-" * 30)
print("Page: " + str(page))
print("-"* 30)
google_search_url = make_google_search_url(page)
browser.get(google_search_url)
html_text = browser.page_source# 得到页面代码
while "Our systems have detected unusual traffic" in html_text:
print("Google Robot!")
time.sleep(10)
html_text = browser.page_source # 得到页面代码
auto_quit_cnt += 1
if auto_quit_cnt > 30:
break
auto_quit_cnt = 0
lofter_list = get_url_from_search(html_text)
browser = find_ao3_from_lofter(lofter_list, browser, "lofter")
写在最后:
关于AO3这个系列,我还剩最后两篇文案: 基于深度学习的 NLP 文本归类器;基于OpenCV 的图像视频制作.这个专题做了快一月了,我期盼能够将我想讲的技术安安静静讲完。而后再带着大众探索其他有意思的编程技术,而不是揪着这个专题不放。
因此再次申明,我只是分析 AO3 其他事情我不做探讨和引申,亦恳请大众理性思考和探讨。上文中我已然有限扩大了讨论范围。我的下一篇文案会根据我的规划来,我的下一个视频会是另一个好玩的技术。
我亦期盼即使你不爱好我,亦不要讨厌技术,不要讨厌学习。
在这段时间之前我是无做Python数据分析的关联知识的;虽然同属深度学习,NLP不是我的专业,因此我亦是第1次实践,然则经过这个热点,我收获了很多新知识,亦有非常多人给我点赞鼓励交流探讨。我收获了非常多。
然则,
你收获了什么呢?
|